zsh variable path array – Difference Between $path and $PATH in zsh

arraypathvariablezsh

In FreeBSD 12, using the zsh shell, I noticed this difference when looking at $path (lowercase) versus $PATH (uppercase).

echo $path

/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin /usr/home/freebsd/bin

echo $PATH

/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/home/freebsd/bin

One output is delimited by SPACE character, the other by COLON character.

➥ Why the difference?

Are these two different, separate variables? Or does the lowercase/uppercase trigger some kind of trick or meaning I do not know about?

Is this a zsh feature? Or a feature of FreeBSD?

Best Answer

That's a feature of zsh inherited from csh/tcsh.

The $path array variable is tied to the $PATH scalar (string) variable. Any modification on one is reflected in the other.

In zsh (contrary to (t)csh), you can tie other variables beside $PATH with typeset -T. It's conventional, but not mandatory, to use an uppercase name for the colon-separated scalar and the same name in lowercase for the array. While colon is the default separator, other separators can be used (for instance newline to tie a multi-line string to an array, or comma to tie a csv row to an array)

In recent versions of zsh, typeset -p PATH or typeset -p path shows the link between the two variables:

% typeset -p path
typeset -aT PATH path=( /home/chazelas/bin /usr/local/bin /usr/bin /bin )

That's useful in that it makes it easier to add remove components or loop over them.

Doing a typeset -U path to make the elements unique also helps keeping the $PATH variable clean (something similar can be achieved in tcsh with set -f).