zsh command substitution fails when assigned to LINES
The problem is the variable name. LINES
is one of the variables with a conventional meaning. Its meaning is to convey the number of lines in a terminal. There is a similar variable COLUMNS
.
One of the jobs of an interactive shell is to update these two variables when the terminal is resized. Both bash and zsh do this. Even in bash, while LINES=$(…)
does work, the value will be overwritten if you resize the terminal.
In zsh, additionally, LINES
and COLUMNS
are declared as integer variables (which makes perfect sense given their purpose). So if you try to assign to them, the string that you assign is interpreted as an arithmetic expression, hence the error if you try to assign a string that isn't a valid arithmetic expression. You can see that the variable is declared as an integer with typeset
:
% typeset -p LINES
typeset -i10 LINES=25
-i
indicates an integer variable, 10
forces it to be represented in base 10 (which is the default anyway).
Don't use variables whose names are used by your shell, such as PATH
, LINES
, PS1
, etc. Unfortunately, there's no namespace for shell or environment variables: you have to share. The zsh manual lists the variables that zsh sets and the variables that zsh uses if the user sets them. The bash manual has a list of variables that it uses or sets.
There is a widespread convention that environment variables and variables that have some meaning to the shell are in all uppercase. But zsh also uses some all-lowercase variables.