В чем разница между $ path и $ PATH (строчными и прописными) в zsh?

13

В FreeBSD 12, используя zshоболочку, я заметил эту разницу, когда смотрю на $path(строчные буквы) и $PATH(прописные).

echo $path

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

echo $PATH

/ SBIN: / бен: / USR / SBIN: / USR / бен: / USR / местные / SBIN: / USR / местные / бен: / USR / дома / FreeBSD / бен

Один вывод ограничен символом пробела, другой - символом COLON.

➥ Почему разница?

Это две разные, отдельные переменные? Или строчная / прописная буква вызывает какой-то фокус или смысл, о котором я не знаю?

Это zshособенность? Или особенность FreeBSD?

Базилик Бурк
источник
1
Кроме того: в любой POSIX-совместимой оболочке имена переменных с любыми строчными символами гарантированно безопасны для использования приложением (не для того, чтобы изменять оболочку или поведение системы при изменении). Это одно из тех мест, где решение zsh следовать стандарту только в тех случаях, когда это имеет для них смысл, может создать головную боль для авторов сценариев, поскольку стандартизированные гарантии не применяются.
Чарльз Даффи
@CharlesDuffy у вас есть ссылка на часть стандарта, где говорится что-либо о переменных нижнего и верхнего регистра? Благодарю.
Мосви
@mosvy, pubs.opengroup.org/onlinepubs/9699919799/basedefs/… - прочитайте его, имея в виду, что переменные оболочки и среды совместно используют одно пространство имен (установка переменной оболочки обновляет значение любой существующей переменной среды с одноименным названием; установка переменной среды инициализирует переменные оболочки). Конкретные строки: пространство имен имен переменных среды, содержащих строчные буквы, зарезервировано для приложений. Приложения могут определять любые переменные среды с именами из этого пространства имен без изменения поведения стандартных утилит.
Чарльз Даффи
@CharlesDuffy Это не относится здесь. Установка pathвнутри zshне будет обновлять какие - либо pathenvvar: path=junk zsh -c 'echo $path; path=garbage; /usr/bin/printenv path'.
Мосвы
@mosvy, ты убедил меня, что это не противоречит букве стандарта. С другой стороны, дух сделал бы for path in "$dir"/*рефлексивно безопасный код для записи.
Чарльз Даффи

Ответы:

20

Это особенность, zshунаследованная от csh/ tcsh.

$path Массив переменная привязана к $PATH скалярной (строка) переменной. Любая модификация одного отражается в другом.

В zsh(вопреки (t)csh) вы можете связать другие переменные $PATHс typeset -T. Обычно, но не обязательно, использовать имя в верхнем регистре для скаляра, разделенного двоеточиями, и то же имя в нижнем регистре для массива. Хотя двоеточие является разделителем по умолчанию, могут использоваться другие разделители (например, символ новой строки для привязки многострочной строки к массиву или запятая для привязки строки csv к массиву)

В последних версиях zsh, typeset -p PATHили typeset -p pathпоказывает связь между двумя переменными:

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

Это полезно тем, что облегчает добавление удаляемых компонентов или их циклическую обработку.

Выполнение a, typeset -U pathчтобы сделать элементы уникальными, также помогает поддерживать $PATHпеременную в чистоте (что-то подобное может быть достигнуто tcshс помощью set -f).

Стефан Шазелас
источник