ZSHPARAM(1)
๐ธ hi bestie, welcome to zshparam ๐ธ
okay so this page is from the General Commands Manual and it's literally all about zsh parameters โ like, the whole lore. it is long so we're doing this in parts, and this is part one. buckle up ๐
โจ NAME โจ
zshparam โ zsh parameters. that's it, that's the name, slay.
๐ DESCRIPTION ๐
okay so a parameter has three things going on: a name, a value, and a number of attributes. and the name? it can be any sequence of alphanumeric characters and underscores, OR it can be one of these single-character icons: *, @, #, ?, -, $, or !. (yes literally just one character. main character energy.)
a parameter whose name begins with an alphanumeric or underscore is also referred to as a variable. iykyk.
the attributes of a parameter decide the type of its value โ people call that the parameter type or variable type โ and they also control other processing that may get applied to the value when it's referenced. the value type can be:
- a scalar (a string, an integer, or a floating point number)
- an array (indexed numerically)
- an associative array (an unordered set of name-value pairs, indexed by name, also referred to as a hash)
named scalar parameters can have the exported, -x, attribute, which copies them into the process environment, and that environment then gets passed from the shell to any new processes it starts. exported parameters are called environment variables. the shell also imports environment variables at startup time and automatically marks the corresponding parameters as exported. ngl, some environment variables are not imported โ for reasons of security, or because they would interfere with the correct operation of other shell features. not everything gets an invite to the party ๐
parameters may also be special, meaning they have a predetermined meaning to the shell. special parameters cannot have their type changed or their readonly attribute turned off, and if a special parameter is unset and then later recreated, the special properties will be retained. iconic, honestly.
to declare the type of a parameter, or to assign a string or numeric value to a scalar parameter, use the typeset builtin. ๐ซถ
the value of a scalar parameter may also be assigned by writing:
name=value
in scalar assignment, value is expanded as a single string, in which the elements of arrays are joined together. filename expansion is not performed unless the option GLOB_ASSIGN is set. noted. โ๏ธ
when the integer attribute, -i, or a floating point attribute, -E or -F, is set for name, the value is subject to arithmetic evaluation. and get this โ by replacing = with +=, a parameter can be incremented or appended to. See the section Array Parameters and Arithmetic Evaluation (in zshmisc(1)) for additional forms of assignment.
not me warning you: assignment may implicitly change the attributes of a parameter. for example, assigning a number to a variable in arithmetic evaluation may change its type to integer or float, and with GLOB_ASSIGN assigning a pattern to a variable may change its type to an array. sneaky but valid ๐
to reference the value of a parameter, write $name or ${name}. See Parameter Expansion in zshexpn(1) for complete details โ that section also explains the effect of the difference between scalar and array assignment on parameter expansion. go read it, bestie, it's giving essential.
๐ฆ ARRAY PARAMETERS ๐ฆ
to assign an array value, write one of:
set -A name value ...
name=(value ...)
name=([key]=value ...)
if no parameter name exists, an ordinary array parameter is created. if the parameter name exists and is a scalar, it is replaced by a new array. out with the old, in with the new ๐
in the third form, key is an expression that will be evaluated in arithmetic context (in its simplest form, an integer) that gives the index of the element to be assigned with value. in this form, any elements not explicitly mentioned that come before the largest index to which a value is assigned are assigned an empty string. the indices may be in any order. and note that this syntax is strict: [ and ]= must not be quoted, and key may not consist of the unquoted string ]=, but is otherwise treated as a simple string. the enhanced forms of subscript expression that may be used when directly subscripting a variable name, described in the section Array Subscripts below, are not available here. rules are rules ๐
the syntaxes with and without the explicit key may be mixed. an implicit key is deduced by incrementing the index from the previously assigned element. note that it is not treated as an error if latter assignments in this form overwrite earlier assignments. no drama.
for example, assuming the option KSH_ARRAYS is not set, the following:
array=(one [3]=three four)
causes the array variable array to contain four elements one, an empty string, three and four, in that order. cute, right? โจ
in the forms where only value is specified, full command line expansion is performed.
in the [key]=value form, both key and value undergo all forms of expansion allowed for single word shell expansions (this does not include filename generation) โ these are as performed by the parameter expansion flag (e) as described in zshexpn(1). nested parentheses may surround value and are included as part of the value, which is joined into a plain string; this differs from ksh which allows the values themselves to be arrays. a future version of zsh may support that. (manifesting ๐) to cause the brackets to be interpreted as a character class for filename generation, and therefore to treat the resulting list of files as a set of values, quote the equal sign using any form of quoting. example:
name=([a-z]'='*)
to append to an array without changing the existing values, use one of the following:
name+=(value ...)
name+=([key]=value ...)
in the second form key may specify an existing index as well as an index off the end of the old array; any existing value is overwritten by value. also, it is possible to use [key]+=value to append to the existing value at that index. so many flavours, all valid ๐
within the parentheses on the right hand side of either form of the assignment, newlines and semicolons are treated the same as white space, separating individual values. any consecutive sequence of such characters has the same effect. basically they're all just vibes separators.
ordinary array parameters may also be explicitly declared with:
typeset -a name
associative arrays must be declared before assignment, by using:
typeset -A name
when name refers to an associative array, the list in an assignment is interpreted as alternating keys and values:
set -A name key value ...
name=(key value ...)
name=([key]=value ...)
heads up bestie: only one of the two syntaxes above may be used in any given assignment โ the forms may not be mixed. this is unlike the case of numerically indexed arrays. pick a lane ๐
every key must have a value in this case. note that this assigns to the entire array, deleting any elements that do not appear in the list. the append syntax may also be used with an associative array:
name+=(key value ...)
name+=([key]=value ...)
this adds a new key/value pair if the key is not already present, and replaces the value for the existing key if it is. in the second form it is also possible to use [key]+=value to append to the existing value at that key. expansion is performed identically to the corresponding forms for normal arrays, as described above. consistency slay ๐
to create an empty array (including associative arrays), use one of:
set -A name
name=()
๐ง Array Subscripts ๐ง
individual elements of an array may be selected using a subscript. a subscript of the form [exp] selects the single element exp, where exp is an arithmetic expression which will be subject to arithmetic expansion as if it were surrounded by $((...)). the elements are numbered beginning with 1, unless the KSH_ARRAYS option is set, in which case they are numbered from zero. know the difference, it matters ๐
subscripts may be used inside braces used to delimit a parameter name, thus ${foo[2]} is equivalent to $foo[2]. if the KSH_ARRAYS option is set, the braced form is the only one that works, as bracketed expressions otherwise are not treated as subscripts. ok queen, use the braces.
if the KSH_ARRAYS option is not set, then by default accesses to an array element with a subscript that evaluates to zero return an empty string, while an attempt to write such an element is treated as an error. for backward compatibility the KSH_ZERO_SUBSCRIPT option can be set to cause subscript values 0 and 1 to be equivalent; see the description of the option in zshoptions(1). legacy behaviour, we respect it ๐ซก
the same subscripting syntax is used for associative arrays, except that no arithmetic expansion is applied to exp. however, the parsing rules for arithmetic expressions still apply, which affects the way that certain special characters must be protected from interpretation. see Subscript Parsing below for details. yes, there's a whole other section. we'll get there.
a subscript of the form [*] or [@] evaluates to all elements of an array; there is no difference between the two except when they appear within double quotes. check it:
"$foo[*]"evaluates to"$foo[1] $foo[2] ...""$foo[@]"evaluates to"$foo[1]" "$foo[2]" ..."
for associative arrays, [*] or [@] evaluate to all the values, in no particular order. note that this does not substitute the keys; see the documentation for the k flag under Parameter Expansion Flags in zshexpn(1) for complete details. when an array parameter is referenced as $name (with no subscript) it evaluates to $name[*], unless the KSH_ARRAYS option is set, in which case it evaluates to ${name[0]} โ and for an associative array, that means the value of the key 0, which may not exist even if there are values for other keys. awkward but true ๐ญ
a subscript of the form [exp1,exp2] selects all elements in the range exp1 to exp2, inclusive. (associative arrays are unordered, and so do not support ranges. sorry bestie.) if one of the subscripts evaluates to a negative number, say -n, then the *n*th element from the end of the array is used. thus $foo[-3] is the third element from the end of the array foo, and $foo[1,-1] is the same as $foo[*]. negative indexing is THAT girl ๐
subscripting may also be performed on non-array values, in which case the subscripts specify a substring to be extracted. for example, if FOO is set to foobar, then echo $FOO[2,5] prints ooba. note that some forms of subscripting described below perform pattern matching, and in that case the substring extends from the start of the match of the first subscript to the end of the match of the second subscript. example:
string="abcdefghijklm"
print ${string[(r)d?,(r)h?]}
prints defghi. this is an obvious generalisation of the rule for single-character matches. for a single subscript, only a single character is referenced (not the range of characters covered by the match). she's precise, she's iconic, she's done with part one ๐ฆ
(part 1 done โ more parts are literally coming, don't go anywhere)
Quick note before we move on, bestie โ in substring ops the second subscript gets treated differently by the r and R flags: r takes the shortest match as the length, R takes the longest match. So with r a * at the end is literally doing nothing (redundant, we love an understudy), while with R it matches the whole rest of the string. ๐
And this doesn't change anything in the single-subscript case, because there the length of the match is irrelevant. Slay.
๐ Array Element Assignment ๐
A subscript can show up on the left side of an assignment, like this:
name[exp]=value
In this form, whatever element or range exp points at gets replaced by the expression on the right side. You can create an array (but not an associative array, bestie, know the difference โจ) by assigning to a range or an element. Arrays do not nest โ so if you assign a parenthesized list of values to an element or a range, that changes the number of elements in the array and shifts the other elements around to make room. (This is not supported for associative arrays, sorry ๐ซถ)
This syntax also works as an argument to the typeset command:
typeset "name[exp]"=value
But heads up: in this case the value may not be a parenthesized list โ with typeset you can only make single-element assignments. Also, the quotes are genuinely necessary here so the brackets don't get read as filename generation operators. (Related: the noglob precommand modifier could be used instead. Options, we love options ๐)
To delete an element of an ordinary array, assign () to that element. To delete an element of an associative array, use the unset command:
unset "name[exp]"
โจ Subscript Flags โจ
Okay so here's the cute part: if the opening bracket โ or the comma in a range โ in any subscript expression is directly followed by an opening parenthesis, then everything up to the matching closing paren counts as a list of flags. Like name[(flags)exp]. Iconic.
The flags s, n and b take an argument; the delimiter is shown below as :, but literally any character works โ or the matching pairs (...), {...}, [...], or <...>. โ ๏ธ One little catch: <...> can only be used if the subscript is inside a double quoted expression or a parameter substitution wrapped in braces, otherwise the expression gets interpreted as a redirection. Not that, bestie.
The flags we currently understand are:
wโ If the parameter you're subscripting is a scalar, this flag makes subscripting work on words instead of characters. Default word separator is whitespace. When you combine it withiorI, the effect is to give you the index of the first character of the first/last word that matches the given pattern; note that a failed match in this case always yields0. ๐ซถs:string:โ This gives the string that separates words (for use with thewflag). The delimiter character:is arbitrary; see above. ๐pโ Recognize the same escape sequences as theprintbuiltin, applied to the string argument of a subsequentsflag. Big brain energy.fโ If the parameter subscripted is a scalar, this makes subscripting work on lines instead of characters, i.e. elements separated by newlines. It's shorthand forpws:\n:. ๐ธrโ Reverse subscripting, my beloved: if this flag is given,expis taken as a pattern and the result is the first matching array element, substring, or word (depending on whether the parameter is an array, a scalar, or a scalar with thewflag given, respectively). The subscript used is the number of the matching element, so pairs of subscripts such as$foo[(r)??,3]and$foo[(r)??,(r)f*]are possible if the parameter is not an associative array. If the parameter is an associative array, only the value part of each pair gets compared to the pattern, and the result is that value. ๐ฆ
If a search through an ordinary array failed, the search sets the subscript to one past the end of the array โ which means ${array[(r)pattern]} will substitute the empty string. So the success of a search can be tested with the (i) flag, for example (assuming the option KSH_ARRAYS is not in effect):
[[ ${array[(i)pattern]} -le ${#array} ]]
If KSH_ARRAYS is in effect, replace the -le with -lt. ๐ญ
Rโ Liker, but gives the last match. For associative arrays, gives all possible matches. May be used for assigning to ordinary array elements, but not for assigning to associative arrays. On failure, for normal arrays this has the effect of returning the element corresponding to subscript0; that's empty unless one of the optionsKSH_ARRAYSorKSH_ZERO_SUBSCRIPTis in effect. ๐
Note that in subscripts with both r and R, pattern characters are active even if they were substituted for a parameter (regardless of the setting of GLOB_SUBST, which controls this feature in normal pattern matching). The flag e can be added to inhibit pattern matching. But since that flag doesn't inhibit other forms of substitution, care is still required โ using a parameter to hold the key has the desired effect:
key2='original key'
print ${array[(Re)$key2]}
iโ Liker, but gives the index of the match instead; this may not be combined with a second argument. On the left side of an assignment, it behaves liker. For associative arrays, the key part of each pair is compared to the pattern, and the first matching key found is the result. On failure it substitutes the length of the array plus one, as discussed underr, or the empty string for an associative array. ๐ฅ
Note: although i may be applied to a scalar substitution to find the offset of a substring, the results are likely to be misleading when searching within substitutions that yield an empty string, or when searching for the empty substring. Don't say I didn't warn you ๐
Iโ Likei, but gives the index of the last match, or all possible matching keys in an associative array. On failure it substitutes0, or the empty string for an associative array. This flag is genuinely the best when testing for values or keys that don't exist. ๐
Note: if the option KSH_ARRAYS is in effect and no match is found, the result is indistinguishable from the case where the first element of the array matches. Awkward. ๐ฌ
kโ If used in a subscript on an associative array, this flag makes the keys be interpreted as patterns, and returns the value for the first key found whereexpis matched by the key. Note this could be any such key, since no ordering of associative arrays is defined. This flag does not work on the left side of an assignment to an associative array element. If used on another type of parameter, it behaves liker. ๐ซKโ On an associative array this is likek, but returns all values whereexpis matched by the keys. On other types of parameters it has the same effect asR. ๐n:expr:โ If combined withr,R,iorI, makes them give the nth or nth-from-last match (ifexprevaluates to n). This flag is ignored when the array is associative. The delimiter character:is arbitrary; see above. โญb:expr:โ If combined withr,R,iorI, makes them begin at the nth or nth-from-last element, word, or character (ifexprevaluates to n). Also ignored when the array is associative. Delimiter character:is arbitrary; see above. ๐eโ This flag causes any pattern matching that would be performed on the subscript to use plain string matching instead. Hence${array[(re)*]}matches only the array element whose value is*. Note that other forms of substitution, like parameter substitution, are not inhibited. ๐ง
This flag can also be used to force * or @ to be interpreted as a single key rather than as a reference to all values. It may be used for either purpose on the left side of an assignment. ๐
See Parameter Expansion Flags (zshexpn(1)) for extra ways to manipulate the results of array subscripting. There's always more lore, iykyk.
๐ฆ Subscript Parsing ๐ฆ
This discussion applies mainly to associative array key strings and to patterns used for reverse subscripting (the r, R, i, etc. flags), but it may also affect parameter substitutions that appear as part of an arithmetic expression in an ordinary subscript. Stay with me, bestie.
To dodge subscript parsing limitations when assigning to associative array elements, use the append syntax:
aa+=('key with "*strange*" characters' 'value string')
The basic rule to remember when writing a subscript expression is that all text between the opening [ and the closing ] is interpreted as if it were inside double quotes (see zshmisc(1)). But โ unlike double quotes, which normally can't nest โ subscript expressions may appear inside double-quoted strings, or inside other subscript expressions (or both!!), so the rules have two important differences. ๐ค
Difference #1: brackets ([ and ]) must appear as balanced pairs inside a subscript expression unless they're preceded by a backslash (\). So inside a subscript expression (and unlike true double-quoting), the sequence \[ becomes [, and likewise \] becomes ]. This applies even when a backslash wouldn't normally be required; for example, the pattern [^[] (to match any character other than an open bracket) should be written [^\[] in a reverse-subscript pattern. However, note that \[^\[\] and even \[^[] mean the same thing, because backslashes are always stripped when they appear before brackets! Wild, I know. ๐
The same rule applies to parentheses (( and )) and braces ({ and }): they must appear either in balanced pairs or preceded by a backslash, and backslashes that protect parentheses or braces get removed during parsing. Why? Because parameter expansions may be surrounded by balanced braces, and subscript flags are introduced by balanced parentheses. It's giving structural integrity. ๐
Difference #2: a double-quote (") may appear as part of a subscript expression without being preceded by a backslash โ which means the two characters \" remain as two characters in the subscript (whereas in true double-quoting, \" becomes "). But because of standard shell quoting rules, any double-quotes that do appear must still occur in balanced pairs unless preceded by a backslash. Which makes it harder to write a subscript expression containing an odd number of double-quote characters ๐ญ โ but the reason for this difference is so that when a subscript expression appears inside true double-quotes, you can still write \" (rather than \\\") for ". And that's the whole vibe. ๐ซถ
okay so if you ever need an odd number of double quotes as a key in an assignment, the move is: use the typeset builtin plus an enclosing pair of double quotes ๐ and to read that key's value back, double quotes again, bestie:
typeset -A aa
typeset "aa[one\"two\"three\"quotes]"=QQQ
print "$aa[one\"two\"three\"quotes]"
It is so important to note that the quoting rules do not change when a parameter expansion with a subscript gets nested inside another subscript expression ๐ like, you do not need extra backslashes inside the inner subscript expression โ they get removed only once, from the innermost subscript outwards. Also, parameters get expanded from the innermost subscript first, as each expansion is encountered left to right in the outer expression โจ
A further complication (ugh, I know ๐ญ) comes from a way in which subscript parsing is not different from double quote parsing. Just like in true double-quoting, the sequences \* and \@ stay as two characters when they show up in a subscript expression. So to use a literal * or @ as an associative array key, you gotta use the e flag:
typeset -A aa
aa[(e)*]=star
print $aa[(e)*]
One last detail you gotta consider when reverse subscripting is happening ๐ฅ parameters appearing in the subscript expression get expanded first, and then the complete expression is interpreted as a pattern. Two effects from this:
- first, parameters behave as if
GLOB_SUBSTwere on (and it cannot be turned off); - second, backslashes are interpreted twice โ once when parsing the array subscript, and again when parsing the pattern.
In a reverse subscript, you need four backslashes to make a single backslash match literally in the pattern ๐ตโ๐ซ For complex patterns, it's often easiest to assign the pattern you want to a parameter and then refer to that parameter in the subscript, because then the backslashes, brackets, parentheses, etc. are seen only when the complete expression is converted to a pattern. And if you wanna match the value of a parameter literally in a reverse subscript rather than as a pattern, use ${(q)name} (see zshexpn(1)) to quote the expanded value ๐ซถ
Real talk: thekandKflags are reverse subscripting for an ordinary array, but they are not reverse subscripting for an associative array! (For an associative array, the keys in the array itself are what get interpreted as patterns by those flags; the subscript is a plain string in that case.) ๐
One final note, and it's not even directly about subscripting: the numeric names of positional parameters (described below) are parsed specially, so for example $2foo is equivalent to ${2}foo. Therefore, to use subscript syntax to extract a substring from a positional parameter, the expansion must be surrounded by braces โ for example, ${2[3,5]} evaluates to the third through fifth characters of the second positional parameter, but $2[3,5] is the entire second parameter concatenated with the filename generation pattern [3,5] ๐
๐ฏ POSITIONAL PARAMETERS
The positional parameters are your backstage pass to the command-line arguments of a shell function, a shell script, or the shell itself ๐ค see the section Invocation, and also the section Functions. The parameter n, where n is a number, is the *n*th positional parameter. The parameter $0 is a special case โ see the section Parameters Set By The Shell.
The parameters *, @ and argv are arrays containing all the positional parameters, so $argv[n], etc., is equivalent to just $n โจ Note that the options KSH_ARRAYS or KSH_ZERO_SUBSCRIPT apply to these arrays too, so with either of those options set, ${argv[0]} is equivalent to $1 and so on ๐
Positional parameters can be changed after the shell or function starts, by using the set builtin, by assigning to the argv array, or by direct assignment of the form n=value where n is the number of the positional parameter you wanna change. This also creates (with empty values) any of the positions from 1 to n that don't already have values ๐ And note that, because positional parameters form an array, an array assignment of the form n=(value ...) is allowed, and it has the effect of shifting all the values at positions greater than n by as many positions as necessary to accommodate the new values ๐ซ
๐ LOCAL PARAMETERS
Shell function executions delimit scopes for shell parameters โ and yeah, parameters are dynamically scoped ๐ธ The typeset builtin, and its alternative forms declare, integer, local and readonly (but not export), can be used to declare a parameter as being local to the innermost scope.
When a parameter is read or assigned to, the innermost existing parameter of that name is used (that is, the local parameter hides any less-local parameter) ๐ However, assigning to a non-existent parameter, or declaring a new parameter with export, causes it to be created in the outermost scope.
Local parameters disappear when their scope ends. unset can be used to delete a parameter while it's still in scope; any outer parameter of the same name stays hidden ๐
Special parameters may also be made local; they retain their special attributes unless either the existing or the newly-created parameter has the -h (hide) attribute. This may have unexpected effects: there is no default value, so if there's no assignment at the point the variable is made local, it will be set to an empty value (or zero in the case of integers) ๐ญ The following:
typeset PATH=/new/directory:$PATH
is valid for temporarily allowing the shell, or programmes called from it, to find the programs in /new/directory inside a function โจ
ngl, the restriction in older versions of zsh that local parameters were never exported? That's been removed ๐
๐ PARAMETERS SET BY THE SHELL
In the parameter lists that follow, the mark <S> means the parameter is special โญ And <Z> means the parameter does not exist when the shell initializes in sh or ksh emulation mode.
The parameters !, #, *, -, ?, @, $, ARGC, HISTCMD, LINENO, PPID, status, TTYIDLE, zsh_eval_context, ZSH_EVAL_CONTEXT, and ZSH_SUBSHELL are read-only and thus cannot be restored by the user, so they are not output by typeset -p. This also applies to many read-only parameters loaded from modules ๐ง
The following parameters are automatically set by the shell ๐
!<S>โ The process ID of the last command started in the background with&, put into the background with thebgbuiltin, or spawned withcoproc.#<S>โ The number of positional parameters in decimal. Note that some confusion may occur with the syntax$#param, which substitutes the length of param. Use${#}to resolve ambiguities. In particular, the sequence$#-...in an arithmetic expression is interpreted as the length of the parameter-, q.v.ARGC<S><Z>โ Same as#.$<S>โ The process ID of this shell, set when the shell initializes. Processes forked from the shell without executing a new program, such as command substitutions and commands grouped with(...), are subshells that duplicate the current shell, and thus substitute the same value for$$as their parent shell.-<S>โ Flags supplied to the shell on invocation or by thesetorsetoptcommands.*<S>โ An array containing the positional parameters.argv<S><Z>โ Same as*. Assigning toargvchanges the local positional parameters, butargvis not itself a local parameter. Deletingargvwithunsetin any function deletes it everywhere, although only the innermost positional parameter array is deleted (so*and@in other scopes are not affected).@<S>โ Same asargv[@], even whenargvis not set.?<S>โ The exit status returned by the last command.0<S>โ The name used to invoke the current shell, or as set by the-ccommand line option upon invocation. If theFUNCTION_ARGZEROoption is set,$0is set upon entry to a shell function to the name of the function, and upon entry to a sourced script to the name of the script, and reset to its previous value when the function or script returns.status<S><Z>โ Same as?.pipestatus<S><Z>โ An array containing the exit statuses returned by all commands in the last pipeline._<S>โ The last argument of the previous command. Also, this parameter is set in the environment of every command executed to the full pathname of the command.CPUTYPEโ The machine type (microprocessor class or machine model), as determined at run time.EGID<S>โ The effective group ID of the shell process. If you have sufficient privileges, you may change the effective group ID of the shell process by assigning to this parameter. Also (assuming sufficient privileges), you may start a single command with a different effective group ID by(EGID=gid; command)
If this is made local, it is not implicitly set to 0, but may be explicitly set locally.
EUID<S>โ The effective user ID of the shell process. If you have sufficient privileges, you may change the effective user ID of the shell process by assigning to this parameter. Also (assuming sufficient privileges), you may start a single command with a different effective user ID by(EUID=uid; command)
If this is made local, it is not implicitly set to 0, but may be explicitly set locally.
ERRNO<S>โ The value oferrno(seeerrno(3)) as set by the most recently failed system call. This value is system dependent and is intended for debugging purposes. It's also useful with thezsh/systemmodule, which lets the number be turned into a name or message ๐ง
To use this parameter, it must first be assigned a value (typically 0 (zero)). It's initially unset for scripting compatibility.
FUNCNEST<S>โ Integer. If greater than or equal to zero, the maximum nesting depth of shell functions. When it's exceeded, an error is raised at the point where a function is called. The default value is determined when the shell is configured, but is typically500. Increasing the value increases the danger of a runaway function recursion causing the shell to crash ๐ Setting a negative value turns off the check.
GID <S>
The real group ID of the shell process, bestie. If you've got sufficient privileges, you can literally change the group ID of the shell process by assigning to this parameter. And also โ assuming sufficient privileges again โ you can start a single command under a different group ID with (GID=gid; command) โจ
If this one is made local, it is not implicitly set to 0, but it may be explicitly set locally. Noted ๐
HISTCMD
The current history event number in an interactive shell โ in other words, the event number for the command that caused $HISTCMD to be read. If the current history event modifies the history, HISTCMD changes to the new maximum history event number. Sneaky but valid ๐ซถ
HOST
The current hostname. That's it, that's the whole vibe ๐
LINENO <S>
The line number of the current line within the current script, sourced file, or shell function being executed โ whichever was started most recently. Lowkey important caveat: in the case of shell functions, the line number refers to the function as it appeared in the original definition, not necessarily as displayed by the functions builtin. So don't come for it when the numbers don't match your scroll position ๐ญ
LOGNAME
If the corresponding variable is not set in the environment of the shell, it's initialized to the login name corresponding to the current login session. This parameter is exported by default, but that can be disabled using the typeset builtin. The value is set to the string returned by the getlogin(3) system call if that's available. fr fr ๐ธ
MACHTYPE
The machine type (microprocessor class or machine model), as determined at compile time. It's giving "who am I, really" energy ๐
OLDPWD
The previous working directory. This is set when the shell initializes and whenever the directory changes. The nostalgic one ๐ฅฒ
OPTARG <S>
The value of the last option argument processed by the getopts command.
OPTIND <S>
The index of the last option argument processed by the getopts command. These two are a package deal, iykyk ๐
OSTYPE
The operating system, as determined at compile time.
PPID <S>
The process ID of the parent of the shell, set when the shell initializes. As with $$, the value does not change in subshells created as a duplicate of the current shell. Main character stays main character ๐
PWD
The present working directory. This is set when the shell initializes and whenever the directory changes โ the present-tense sibling of OLDPWD ๐ฆ
RANDOM <S>
A pseudo-random integer from 0 to 32767, newly generated each time this parameter is referenced. The random number generator can be seeded by assigning a numeric value to RANDOM. Obsessed with the chaos ๐ฅ
The values of RANDOM form an intentionally-repeatable pseudo-random sequence, so subshells that reference RANDOM will result in identical pseudo-random values unless the value of RANDOM is referenced or seeded in the parent shell in between subshell invocations. Yes, this is on purpose. No, it's not a bug ๐
SECONDS <S>
The number of seconds since shell invocation. If this parameter is assigned a value, then the value returned upon reference will be the value that was assigned plus the number of seconds since the assignment. Time math, slay โฑ๏ธ
Unlike other special parameters, the type of the SECONDS parameter can be changed using the typeset command. The type may be changed only to one of the floating point types or back to integer. For example, typeset -F SECONDS causes the value to be reported as a floating point number. The value is available to microsecond accuracy, although the shell may show more or fewer digits depending on the use of typeset. See the documentation for the builtin typeset in zshbuiltins(1) for more details. ๐
SHLVL <S>
Incremented by one each time a new shell is started. Shell inception, basically ๐
signals
An array containing the names of the signals. Note that with the standard zsh numbering of array indices, where the first element has index 1, the signals are offset by 1 from the signal number used by the operating system. For example, on typical Unix-like systems HUP is signal number 1, but is referred to as $signals[2]. This is because of EXIT at position 1 in the array, which is used internally by zsh but is not known to the operating system. ๐
On many systems there is a block of reserved or unused signal numbers before the POSIX real-time signals, so the array index can't be used as an accurate indicator of their signal number. Use, for example, kill -l SIGRTMIN instead. Don't let the index lie to you ๐
TRY_BLOCK_ERROR <S>
In an always block, indicates whether the preceding list of code caused an error. The value is 1 to indicate an error, 0 otherwise. It may be reset, clearing the error condition. See Complex Commands in zshmisc(1).
TRY_BLOCK_INTERRUPT <S>
This variable works in a similar way to TRY_BLOCK_ERROR, but represents the status of an interrupt from the signal SIGINT, which typically comes from the keyboard when the user types Ctrl+C. If set to 0, any such interrupt will be reset; otherwise, the interrupt is propagated after the always block. ๐ซถ
Heads up, bestie: it is possible that an interrupt arrives during the execution of the always block โ and this interrupt is also propagated. Timing is everything, and sometimes the timing is rude ๐ญ
TTY
The name of the tty associated with the shell, if any.
TTYIDLE <S>
The idle time of the tty associated with the shell in seconds, or -1 if there is no such tty. Touch grass metric, essentially ๐ฑ
UID <S>
The real user ID of the shell process. If you have sufficient privileges, you may change the user ID of the shell by assigning to this parameter. Also (assuming sufficient privileges), you may start a single command under a different user ID by (UID=uid; command) โจ
If this is made local, it is not implicitly set to 0, but may be explicitly set locally. Same policy as GID, we keep it consistent ๐
USERNAME <S>
The username corresponding to the real user ID of the shell process. If you have sufficient privileges, you may change the username (and also the user ID and group ID) of the shell by assigning to this parameter. Also (assuming sufficient privileges), you may start a single command under a different username (and user ID and group ID) by (USERNAME=username; command). It's giving identity crisis but make it authorized ๐
VENDOR
The vendor, as determined at compile time.
zsh_eval_context <S> <Z> (ZSH_EVAL_CONTEXT <S>)
An array (colon-separated list) indicating the context of shell code that is being run. Each time a piece of shell code that is stored within the shell is executed, a string is temporarily appended to the array to indicate the type of operation that is being performed. Read in order, the array gives an indication of the stack of operations being performed, with the most immediate context last. The receipts, basically ๐งพ
Note that the variable does not give information on syntactic context such as pipelines or subshells. Use $ZSH_SUBSHELL to detect subshells. Different question, different tool ๐ฆ
The context is one of the following:
cmdargโ code specified by the-coption to the command line that invoked the shell.cmdsubstโ command substitution using the`...`or$(...)construct.equalsubstโ file substitution using the=(...)construct.evalโ code executed by theevalbuiltin.evalautofuncโ code executed with theKSH_AUTOLOADmechanism in order to define an autoloaded function.fcโ code from the shell history executed by the-eoption to thefcbuiltin.fileโ lines of code being read directly from a file, for example by thesourcebuiltin.filecodeโ lines of code being read from a.zwcfile instead of directly from the source file.globqualโ code executed by theeor+glob qualifier.globsortโ code executed to order files by theoglob qualifier.insubstโ file substitution using the<(...)construct.loadautofuncโ code read directly from a file to define an autoloaded function.outsubstโ file substitution using the>(...)construct.schedโ code executed by theschedbuiltin.shfuncโ a shell function.sttyโ code passed tosttyby theSTTYenvironment variable. Normally this is passed directly to the system'ssttycommand, so this value is unlikely to be seen in practice.styleโ code executed as part of a style retrieved by thezstylebuiltin from thezsh/zutilmodule.toplevelโ the highest execution level of a script or interactive shell.trapโ code executed as a trap defined by thetrapbuiltin. Traps defined as functions have the contextshfunc. As traps are asynchronous they may have a different hierarchy from other code.zptyโ code executed by thezptybuiltin from thezsh/zptymodule.zregexparse-guardโ code executed as a guard by thezregexparsecommand from thezsh/zutilmodule.zregexparse-actionโ code executed as an action by thezregexparsecommand from thezsh/zutilmodule.
ZSH_ARGZERO
If zsh was invoked to run a script, this is the name of the script. Otherwise, it is the name used to invoke the current shell. This is the same as the value of $0 when the POSIX_ARGZERO option is set, but is always available. Reliable queen ๐
ZSH_EXECUTION_STRING
If the shell was started with the option -c, this contains the argument passed to the option. Otherwise it is not set.
ZSH_NAME
Expands to the basename of the command used to invoke this instance of zsh. Just the name, no path drama ๐
ZSH_PATCHLEVEL
The output of git describe --tags --long for the zsh repository used to build the shell. This is most useful in order to keep track of versions of the shell during development between releases; hence most users should not use it and should instead rely on $ZSH_VERSION. Devs only, respectfully ๐
zsh_scheduled_events
See the section The zsh/sched Module in zshmodules(1).
ZSH_SCRIPT
If zsh was invoked to run a script, this is the name of the script, otherwise it is unset. Simple as that ๐ธ
ZSH_SUBSHELLโ readonly integer, bestie, you cannot touch this one. Starts at zero and gets bumped by one every single time the shell forks to make a subshell for running code. So(print $ZSH_SUBSHELL)andprint $(print $ZSH_SUBSHELL)both spit out1, but( (print $ZSH_SUBSHELL) )gives you2โ nesting is real ๐ZSH_VERSIONโ literally just the version number of the zsh release you're running. That's it, that's the whole vibe ๐
โจ PARAMETERS USED BY THE SHELL โจ
Okay so these are the parameters the shell itself actually uses โ like, they're not just sitting there being cute, the shell is actively reading them. Quick legend reminder because we love a key: <S> means the parameter is special, and <Z> means the parameter doesn't exist when the shell initializes in sh or ksh emulation mode. ๐ซถ
So when you've got two parameters with the same name but one's upper and one's lowercase โ think path and PATH โ the lowercase one is the array and the uppercase one is a scalar with all the array's elements joined up by colons. They're basically tied parameters like the ones you make with typeset -T. The colon-separated version is your girl for exporting to the environment, and the array version is way easier to actually mess with inside the shell. And heads up: unsetting either one of the pair unsettings the other ๐ญ they keep their special properties when you recreate them, and recreating one recreates the other. Package deal, no cap.
ARGV0โ if you export it, its value becomes theargv[0]of external commands. Classic move is stuff likeARGV0=emacs nethackโ iconic little identity crisis for your process ๐ญBAUDโ the rate in bits per second at which data reaches your terminal. The line editor uses this to compensate for a slow terminal by delaying updates to the display until it actually needs them. If the parameter is unset, or its value is zero, the compensation mechanism is just off. Not set by default, so don't come for her.
This one's genuinely worth setting in some situations, like slow modems dialing into a communications server, or on a slow wide area network. For best performance, set it to the baud rate of the slowest part of the link. Slay, but slowly ๐
cdpath<S> <Z> (CDPATH<S>) โ an array (aka a colon-separated list) of directories that specifies the search path for thecdcommand.COLUMNS<S> โ how many columns your terminal session has. Used for printing select lists and for the line editor. She's all about the width ๐CORRECT_IGNOREโ if set, it's treated as a pattern during spelling correction, and any potential correction that matches the pattern gets ignored. Example: if the value is_*then completion functions โ which by convention have names starting with_โ will never be offered as spelling corrections. One thing though: the pattern does not apply to the correction of file names, like the kindCORRECT_ALLdoes. So with that same example, files in the current directory that begin with_would still get completed. Careful bestie ๐CORRECT_IGNORE_FILEโ if set, it's treated as a pattern during spelling correction of file names. Any file name matching the pattern is never offered as a correction. For example, if the value is.*then dot file names never get offered as spelling corrections. Super useful with theCORRECT_ALLoption โจDIRSTACKSIZEโ the maximum size of the directory stack. By default there's no limit at all. If the stack gets bigger than this, it gets truncated automatically. Great with theAUTO_PUSHDoption ๐ENVโ if theENVenvironment variable is set when zsh is invoked asshorksh, then$ENVis sourced after the profile scripts. Its value gets subjected to parameter expansion, command substitution, and arithmetic expansion before it's interpreted as a pathname. Note thatENVis not used unless the shell is interactive and zsh is emulatingshorksh. Conditional queen ๐FCEDITโ the default editor for thefcbuiltin. IfFCEDITisn't set, thenEDITORgets used; if that's not set either, a builtin default is used, usuallyvi. The fallback chain is giving very prepared ๐ซถfignore<S> <Z> (FIGNORE<S>) โ an array (colon-separated list) holding the suffixes of files to be ignored during filename completion. But plot twist: if completion only generates files with suffixes in this list, then those files get completed anyway. She's stubborn but fair ๐fpath<S> <Z> (FPATH<S>) โ an array (colon-separated list) of directories specifying the search path for function definitions. This path gets searched when a function with the-uattribute is referenced. If an executable file is found, it's read and executed in the current environment. Very demure, very in-place ๐histchars<S> โ three characters used by the shell's history and lexical analysis mechanism:- the first character signals the start of a history expansion (default
!) - the second character signals the start of a quick history substitution (default
^) - the third character is the comment character (default
#)
- the first character signals the start of a history expansion (default
These characters must be in the ASCII character set โ any attempt to set histchars to characters with a locale-dependent meaning gets rejected with an error message. No cap, it'll just refuse you ๐
HISTCHARS<S> <Z> โ same ashistchars. Also (Deprecated.) so like, she's still here but she's retired ๐ตHISTFILEโ the file your history gets saved into when an interactive shell exits. If it's unset, the history is simply not saved. Tragic, honestly ๐ญHISTORY_IGNOREโ if set, it's treated as a pattern at the time history files are written, and any potential history entry matching the pattern gets skipped. For example, if the value isfc *then commands that invoke the interactive history editor never get written to the history file. Clean ๐งผ
Note that HISTORY_IGNORE defines a single pattern โ if you want alternatives, use the (first|second|...) syntax.
Compare the HIST_NO_STORE option or the zshaddhistory hook, either of which would prevent such commands from being added to the interactive history at all. If you want to use HISTORY_IGNORE to stop history being added in the first place, you can define this hook:
zshaddhistory() {
emulate -L zsh
## uncomment if HISTORY_IGNORE
## should use EXTENDED_GLOB syntax
# setopt extendedglob
[[ $1 != ${~HISTORY_IGNORE} ]]
}
HISTSIZE<S> โ the maximum number of events stored in the internal history list. If you're using theHIST_EXPIRE_DUPS_FIRSToption, setting this larger than theSAVEHISTsize gives you the difference as a cushion for saving duplicated history events. Comfy buffer energy โจ
Also: if this is made local, it is not implicitly set to 0 โ but you can explicitly set it locally if you want.
HOME<S> โ the default argument for thecdcommand. Not set automatically by the shell insh,kshorcshemulation, but it's typically hanging out in the environment anyway, and if it does become set, it has its usual special behaviour. Home sweet home ๐IFS<S> โ internal field separators (by default space, tab, newline and NUL) used to separate words resulting from command or parameter expansion, and words read by thereadbuiltin. Any characters from the set space, tab and newline that appear inIFSare called IFS white space. One or more IFS white space characters, or one non-IFS white space character together with any adjacent IFS white space character, delimit a field. And if an IFS white space character appears twice consecutively inIFS, that character is treated as if it were not an IFS white space character. Delulu but consistent ๐
If the parameter is unset, the default is used โ and note that this has a different effect from setting the parameter to an empty string. Important distinction, ngl.
If the MULTIBYTE option is on and IFS contains invalid characters in the current locale, it gets reset to the default. Safety net ๐ธ
KEYBOARD_HACKโ this variable defines a character to be removed from the end of the command line before interpreting it (interactive shells only). It's meant to fix that problem where keys are placed annoyingly close to return, and it replaces theSUNKEYBOARDHACKoption which only did this for backquotes. If the chosen character is one of singlequote, doublequote or backquote, there must also be an odd number of them on the command line for the last one to be removed. Rules are rules ๐
For backward compatibility: if the SUNKEYBOARDHACK option is explicitly set, the value of KEYBOARD_HACK reverts to backquote. If the option is explicitly unset, this variable is set to empty.
KEYTIMEOUTโ the time the shell waits, in hundredths of a second, for another key to be pressed when reading bound multi-character sequences. Patience is a virtue โณLANG<S> โ determines the locale category for any category not specifically selected via a variable starting withLC_.LC_ALL<S> โ overrides the value of theLANGvariable and the value of any of the other variables starting withLC_. She's the final boss ๐LC_COLLATE<S> โ determines the locale category for character collation info within ranges in glob brackets and for sorting. Alphabetize responsibly ๐คLC_CTYPE<S> โ determines the locale category for character handling functions. If theMULTIBYTEoption is in effect, this variable orLANGshould contain a value reflecting the character set in use โ even if it's a single-byte character set โ unless only the 7-bit subset (ASCII) is used. For example, if the character set is ISO-8859-1, a suitable value might been_US.iso88591(certain Linux distributions) oren_US.ISO8859-1(MacOS). Know your encoding, bestie ๐งLC_MESSAGES<S> โ determines the language in which messages should be written. Note that zsh does not use message catalogs. Just so you know ๐ฌLC_NUMERIC<S> โ affects the decimal point character and thousands separator character for the formatted input/output functions and string conversion functions. Big note: zsh ignores this setting when parsing floating point mathematical expressions. Math stays math ๐ฅLC_TIME<S> โ determines the locale category for date and time formatting in prompt escape sequences. Clock girl behaviour ๐LINES<S> โ the number of lines for this terminal session. Used for printing select lists and for the line editor. Height check โจLISTMAXโ in the line editor, this is how many matches get listed without asking first โจ. Negative value? Then the list gets shown if it spans at most that many lines (absolute value, babes). Set it to zero and the shell only asks if the top of the listing would scroll off the screen. Very demure, very mindful.MAILโ if this one's set andmailpathis not set, the shell goes looking for mail in the file you specified ๐.MAILCHECKโ the interval, in seconds, between checks for new mail. Your lil mail-checking heartbeat โฐ.mailpath<S> <Z> (MAILPATH<S>) โ an array (colon-separated list) of filenames to check for new mail ๐ฌ. Each filename can be followed by a?and a message that will be printed. That message undergoes parameter expansion, command substitution and arithmetic expansion with the variable$_defined as the name of the file that has changed. The default message isYou have new mail. And plot twist: if an element is a directory instead of a file, the shell will recursively check every file in every subdirectory of the element ๐manpath<S> <Z> (MANPATH<S> <Z>) โ an array (colon-separated list) whose value the shell itself does not use. Lowkey useless to zsh, highkey useful to you, because setting it also setsMANPATH, and vice versa. Bestie maths ๐งฎ.matchmbeginmendโ arrays set by the shell when thebglobbing flag is used in pattern matches. See the subsection Globbing flags in the documentation for Filename Generation inzshexpn(1)๐ฆ.MATCHMBEGINMENDโ set by the shell when themglobbing flag is used in pattern matches. Same deal: see the subsection Globbing flags in the documentation for Filename Generation inzshexpn(1)๐ธ.module_path<S> <Z> (MODULE_PATH<S>) โ an array (colon-separated list) of directories thatzmodloadsearches for dynamically loadable modules ๐งฉ. It's initialized to a standard pathname, usually/usr/local/lib/zsh/$ZSH_VERSION. (The/usr/local/libpart varies from installation to installation, jsyk.) For security reasons, any value set in the environment when the shell is started will be ignored โ no sneaky env smuggling, periodt ๐.
These parameters only exist if the installation supports dynamic module loading. No modules, no parameter, no drama.
NULLCMD<S> โ the command name to assume if a redirection is specified with no command. Defaults tocat๐. Want sh/ksh behavior? Change this to:. Want csh-like behavior? Unset this parameter entirely โ then the shell will print an error message if null commands are entered. Choose your fighter ๐ .path<S> <Z> (PATH<S>) โ an array (colon-separated list) of directories to search for commands ๐. When you set this parameter, each directory is scanned and all files found are put in a hash table. Directories named by relative path are not scanned for hashing โ noted, moving on ๐.POSTEDIT<S> โ this string is output whenever the line editor exits. It usually contains termcap strings to reset the terminal, i.e. your little goodbye-and-clean-up ritual ๐.PROMPT<S> <Z>PROMPT2<S> <Z>PROMPT3<S> <Z>PROMPT4<S> <Z> โ same asPS1,PS2,PS3andPS4, respectively. Aliases, but make it fashion โจ.prompt<S> <Z> โ same asPS1. That's it. That's the entry ๐ซถ.PROMPT_EOL_MARKโ when thePROMPT_CRandPROMPT_SPoptions are set, this parameter customizes how the end of partial lines are shown ๐๏ธ. It undergoes prompt expansion, with thePROMPT_PERCENToption set. If it's not set, the default behavior is equivalent to the value%B%S%#%s%b. Iconic default, ngl.PS1<S> โ the primary prompt string, printed before a command is read ๐. It undergoes a special form of expansion before being displayed; see EXPANSION OF PROMPT SEQUENCES inzshmisc(1). The default is%m%#โ yes, with that trailing space, don't @ me.PS2<S> โ the secondary prompt, printed when the shell needs more information to complete a command ๐ค. It's expanded in the same way asPS1. Default is%_>, which displays any shell constructs or quotation marks currently being processed. So you can literally see what the shell is still waiting on.PS3<S> โ the selection prompt used within aselectloop ๐ฏ. Expanded in the same way asPS1. The default is?#.PS4<S> โ the execution trace prompt ๐. Default is+%N:%i>, which displays the name of the current shell structure and the line number within it. In sh or ksh emulation, the default is+.psvar<S> <Z> (PSVAR<S>) โ an array (colon-separated list) whose elements can be used inPROMPTstrings ๐ฆ. Settingpsvaralso setsPSVAR, and vice versa. Symmetry slay.READNULLCMD<S> โ the command name to assume if a single input redirection is specified with no command. Defaults tomore๐.REPORTMEMORYโ if nonnegative, commands whose maximum resident set size (roughly speaking, main memory usage) in kilobytes is greater than this value have timing statistics reported ๐ง . The format used to output statistics is the value of theTIMEFMTparameter, which is the same as for theREPORTTIMEvariable and thetimebuiltin; note that by default this does not output memory usage. Appending" max RSS %M"to the value ofTIMEFMTcauses it to output the value that triggered the report. IfREPORTTIMEis also in use, at most a single report is printed for both triggers. This feature requires thegetrusage()system call, commonly supported by modern Unix-like systems.REPORTTIMEโ if nonnegative, commands whose combined user and system execution times (measured in seconds) are greater than this value have timing statistics printed for them โฑ๏ธ. Output is suppressed for commands executed within the line editor, including completion; commands explicitly marked with thetimekeyword still cause the summary to be printed in this case.REPLYโ this parameter is reserved by convention to pass string values between shell scripts and shell builtins in situations where a function call or redirection are impossible or undesirable ๐จ. Thereadbuiltin and theselectcomplex command may setREPLY, and filename generation both sets and examines its value when evaluating certain expressions. Some modules also employREPLYfor similar purposes. It's the group chat of shell parameters, honestly.replyโ asREPLY, but for array values rather than strings. Arrays, but make it a reply ๐ฌ.RPROMPT<S>RPS1<S> โ this prompt is displayed on the right-hand side of the screen when the primary prompt is being displayed on the left ๐. Heads up: this does not work if theSINGLE_LINE_ZLEoption is set. It's expanded in the same way asPS1.RPROMPT2<S>RPS2<S> โ this prompt is displayed on the right-hand side of the screen when the secondary prompt is being displayed on the left ๐ธ. Also does not work if theSINGLE_LINE_ZLEoption is set. It's expanded in the same way asPS2.SAVEHISTโ the maximum number of history events to save in the history file ๐.
If this is made local, it is not implicitly set to 0, but may be explicitly set locally. Local girlies, read that twice.
SPROMPT<S> โ the prompt used for spelling correction ๐ค. The sequence%Rexpands to the string which presumably needs spelling correction, and%rexpands to the proposed correction. All other prompt escapes are also allowed.
The actions available at the prompt are [nyae]:
n(no) (default) โ discard the correction and run the command.y(yes) โ make the correction and run the command.a(abort) โ discard the entire command line without running it.e(edit) โ resume editing the command line.
Pick your path, bestie. Choose wisely ๐ .
STTYโ if this parameter is set in a command's environment, the shell runs thesttycommand with the value of this parameter as arguments in order to set up the terminal before executing the command ๐ฅ๏ธ. The modes apply only to the command, and are reset when it finishes or is suspended. If the command is suspended and continued later with thefgorwaitbuiltins it will see the modes specified bySTTY, as if it were not suspended. This (intentionally) does not apply if the command is continued viakill -CONT.STTYis ignored if the command is run in the background, or if it is in the environment of the shell but not explicitly assigned to in the input line. This avoids runningsttyat every external command by accidentally exporting it. Also note thatSTTYshould not be used for window size specifications; those will not be local to the command.
If the parameter is set and empty, all of the above applies except that stty is not run. This can be useful as a way to freeze the tty around a single command, blocking its changes to tty settings, similar to the ttyctl builtin. Freeze frame, but for your terminal โ๏ธ.
TERM<S> โ the type of terminal in use ๐ฑ๏ธ. This is used when looking up termcap sequences. An assignment toTERMcauses zsh to re-initialize the terminal, even if the value does not change (e.g.,TERM=$TERM). It is necessary to make such an assignment upon any change to the terminal definition database or terminal type in order for the new settings to take effect. Yes, the classicTERM=$TERMtrick โ it's not a no-op, it's a refresh, iykyk.TERMINFO<S> โ a reference to your terminfo database, used by theterminfolibrary when the system has it; seeterminfo(5)๐. If set, this causes the shell to reinitialise the terminal, making the workaroundTERM=$TERMunnecessary. Glow up ๐.TERMINFO_DIRS<S> โ a colon-separated list of terminfo databases, used by theterminfolibrary when the system has it; seeterminfo(5)๐๏ธ. This variable is only used by certain terminal libraries, in particular ncurses; seeterminfo(5)to check support on your system. If set, this causes the shell to reinitialise the terminal, making the workaroundTERM=$TERMunnecessary. Note that unlike other colon-separated arrays this is not tied to a zsh array โ it's out here living its own independent life, main character energy ๐.TIMEFMTโ the format of process time reports with thetimekeyword โณ. The default is%J %U user %S system %P cpu %*E total. Recognizes the following escape sequences, although not all may be available on all systems, and some that are available may not be useful:
%%โ literally just outputs a%. that's it, that's the whole vibe ๐%Uโ CPU seconds spent in user mode โฑ๏ธ%Sโ CPU seconds spent in kernel mode ๐ง%Eโ elapsed time, in seconds โณ%Pโ the CPU percentage, computed as 100*(%U+%S)/%E ๐%Wโ how many times the process was swapped ๐%Xโ the average amount in (shared) text space used, in kilobytes ๐%Dโ the average amount in (unshared) data/stack space used, in kilobytes ๐๏ธ%Kโ the total space used (%X+%D), in kilobytes ๐พ%Mโ the max memory the process had in use at any one time, in kilobytes ๐%Fโ the number of major page faults (page needed to be brought from disk) ๐ฝ%Rโ the number of minor page faults ๐ซ%Iโ the number of input operations ๐ฅ%Oโ the number of output operations ๐ค%rโ the number of socket messages received ๐ก%sโ the number of socket messages sent ๐ถ%kโ the number of signals received ๐จ%wโ number of voluntary context switches (waits) ๐%cโ number of involuntary context switches ๐ตโ๐ซ%Jโ the name of this job ๐
okay and here's a cute little flex: you can slip a star in between the percent sign and the flags that print time (like %*E) and it makes the time print out in hh:mm:ss.ttt format โ hours and minutes only get printed if they're not zero, ngl that's so clean โจ
or, if you're feeling metric, m or u can go there instead (like %mE) and you get your time output in milliseconds or microseconds respectively. pick your unit, bestie ๐ซถ
TMOUT โ if this parameter is nonzero, the shell gets an ALRM signal if a command is not entered within however many seconds you specified after issuing a prompt โฐ if there's a trap on SIGALRM, it gets executed and a brand new alarm is scheduled using the value of the TMOUT parameter after the trap runs. but if no trap is set, and the idle time of the terminal is not less than the value of the TMOUT parameter, zsh terminates. otherwise a new alarm is scheduled to TMOUT seconds after the last keypress. so likeโฆ set it, but know what you're doing ๐
TMPPREFIX โ a pathname prefix the shell uses for all its temporary files ๐๏ธ note that this should include an initial part for the filename as well as any directory names. the default is /tmp/zsh.
TMPSUFFIX โ a filename suffix the shell uses for temporary files created by process substitutions (e.g. =(list)) ๐ง note that the value should include a leading dot . if you want it interpreted as a file extension. the default is to not append any suffix at all โ so, like, only assign this when you actually need it, then unset it again. we love a clean exit ๐
WORDCHARS <S> โ a list of non-alphanumeric characters that the line editor considers part of a word ๐ค
ZBEEP โ if set, this gives you a string of characters that gets output to the terminal instead of beeping. it can use all the same codes as the bindkey command, as described in the zsh/zle module entry in zshmodules(1) ๐ต this may have a visible instead of an audible effect โ for example, the string \e[?5h\e[?5l on a vt100 or xterm will have the effect of flashing reverse video on and off (and if you usually use reverse video, you should use the string \e[?5l\e[?5h instead, bestie, flip it) ๐ฆ this takes precedence over the NOBEEP option, no cap.
ZDOTDIR โ the directory to search for shell startup files (.zshrc, etc), if not $HOME ๐
๐ธ zle_bracketed_paste ๐ธ
so many terminal emulators have a feature that lets applications identify when text is pasted into the terminal rather than being typed normally. for ZLE, that means special characters like tabs and newlines can actually be inserted instead of invoking editor commands ๐ and like, furthermore, pasted text forms a single undo event, and if the region is active, pasted text will replace the region. iconic behaviour honestly ๐
this two-element array contains the terminal escape sequences for enabling and disabling the feature ๐ง these escape sequences are used to enable bracketed paste when ZLE is active and disable it at other times. unsetting the parameter has the effect of ensuring that bracketed paste remains disabled. periodt.
๐ zle_highlight ๐
an array describing contexts in which ZLE should highlight the input text ๐๏ธ see Character Highlighting in zshzle(1) for the full lore.
๐ ZLE_LINE_ABORTED ๐
this parameter is set by the line editor when an error occurs ๐ญ it contains the line that was being edited at the point of the error. print -zr -- $ZLE_LINE_ABORTED can be used to recover the line โ literally your safety net fr fr. only the most recent line of this kind is remembered, so don't get cocky ๐ซ
๐ฆ ZLE_REMOVE_SUFFIX_CHARS and ZLE_SPACE_SUFFIX_CHARS ๐ฆ
these parameters are used by the line editor. in certain circumstances, suffixes (typically space or slash) added by the completion system will be removed automatically โ either because the next editing command wasn't an insertable character, or because the character was marked as requiring the suffix to be removed ๐งน
these variables can contain the sets of characters that will cause the suffix to be removed. if ZLE_REMOVE_SUFFIX_CHARS is set, those characters will cause the suffix to be removed; if ZLE_SPACE_SUFFIX_CHARS is set, those characters will cause the suffix to be removed and replaced by a space โจ
if ZLE_REMOVE_SUFFIX_CHARS is not set, the default behaviour is equivalent to:
ZLE_REMOVE_SUFFIX_CHARS=$' \t\n;&|'
if ZLE_REMOVE_SUFFIX_CHARS is set but is empty, no characters have this behaviour. ZLE_SPACE_SUFFIX_CHARS takes precedence, so that the following:
ZLE_SPACE_SUFFIX_CHARS=$'&|'
causes the characters & and | to remove the suffix but to replace it with a space ๐ซถ
to illustrate the difference โ suppose the option AUTO_REMOVE_SLASH is in effect and the directory DIR has just been completed, with an appended /, and following which the user types &:
- the default result is
DIR&๐ - with
ZLE_REMOVE_SUFFIX_CHARSset but without including&, the result isDIR/&๐ฌ - with
ZLE_SPACE_SUFFIX_CHARSset to include&, the result isDIR &๐
heads up bestie: certain completions may provide their own suffix removal or replacement behaviour which overrides the values described here. see the completion system documentation in zshcompsys(1) ๐
โญ ZLE_RPROMPT_INDENT <S> โญ
if set, this is used to give the indentation between the right hand side of the right prompt in the line editor โ as given by RPS1 or RPROMPT โ and the right hand side of the screen ๐ if not set, the value 1 is used.
typically you'd use this to set the value to 0 so the prompt appears flush with the right hand side of the screen. this is not the default because many terminals do not handle this correctly, in particular when the prompt appears at the extreme bottom right of the screen ๐ต recent virtual terminals are more likely to handle this case correctly. some experimentation is necessary โ go forth and fiddle, you got this ๐งช
and that's a wrap on zshparam(1), bestie!! ๐โจ this was zsh 5.9.2, dated July 12, 2026 โ go forth, set your parameters responsibly, and slay ๐
๐
๐ฆ where this page comes from
- arch rolling: zsh 5.9.2-1 ยท custom
- nixpkgs unstable: zsh 5.9.2
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms