Значение \ перед переменной окружения

Значение \ перед переменной окружения

В ksh на старом компьютере Solaris я использовал:

export PS1="$PWD $"

чтобы установить приглашение на текущий каталог. Это работает отлично, пока вы не сделаете cd в другом месте, тогда вы увидите, что он не оценивает PWD каждый раз. Я заметил, что это исправляется установкой PS1 следующим образом:

export PS1="\$PWD $"

Просто интересно, как это называется, как работает, есть ли другие приложения и т. д. (Это одна из тех вещей, которые довольно трудно найти в Google.)

решение1

Несколько фрагментов документации помогут это объяснить.

ИзДокумент стандартов POSIX для оболочки:

Следующие переменные влияют на выполнение оболочки:
PS1: Каждый раз, когда интерактивная оболочка готова прочитать команду, значение этой переменной должно быть подвергнуто расширению параметров и записано в стандартный поток ошибок.
...
Одинарные кавычки
Заключение символов в одинарные кавычки должно сохранять буквальное значение каждого символа внутри одинарных кавычек.
...
Двойные кавычки
Заключение символов в двойные кавычки должно сохранять буквальное значение всех символов внутри двойных кавычек, за исключением
$: Знак доллара должен сохранять свое особое значение, вводя расширение параметров
...
Символ экранирования (обратная косая черта)
Обратная косая черта, не заключенная в кавычки, должна сохранять буквальное значение следующего символа.

Итак, значение PS1подлежит расширению параметра, и это то, что вам нужно, поэтому оно $PWDбудет оцениваться каждый раз, когда вы получаете приглашение. Это означает, что $PWDв значении должна быть фактическая строка PS1. Но,

PS1="$PWD $ "

установит значениеPWD во время выполнения оператора присваиванияв PS1. PS1будет что-то вроде /home/poldie $, и это никогда не изменится после этого. Вы этого не хотите.

PS1="\$PWD $ "

Обратная косая черта заключает в кавычки $, так что это PS1содержит буквальную строку $PWD $. Вам это нужно.

PS1='$PWD $ '

сделает то же самое. Параметры не раскрываются, если заключены в одинарные кавычки.

(Примечание: изначально все это было у меня в виде exportоператоров, потому что автор решил написать их в виде exportоператоров. @Kusalananda удалил их. Не знаю, почему. Экспорт PS1 — допустимый выбор, если вы хотите, чтобы дочерние оболочки (например, созданные командой :shв vi) сохраняли ваше пользовательское приглашение.)

решение2

Символ \экранирует следующий (специальный) символ. В этом случае он экранирует $, который мы обычно используем для разыменования переменной. Когда оболочка оценивает назначение переменной, она сначала расширяет правую часть выражения. Без перед \, $PWDоболочка расширяет $PWDи присваивает результат PS1.

Однако с \, оболочка обрабатывает $PWDкак литеральную строку и присваивает ее как есть PS1, так что PS1содержит строку $PWD, а не развернутое значение переменной $PWD. Когда оболочка собирается отобразить приглашение, она снова выполняет расширение переменной, и на этот раз, поскольку $PS1содержит $PWD,без\, оболочка успешно расширяет его до текущего каталога.

Тот же подход можно использовать для создания динамических имен переменных в скриптах оболочки ( rcNGсистема NetBSD использует это довольно широко, особенно в скриптах, управляющих сетевыми интерфейсами, где количество обозначений сетевых адаптеров в NetBSD и FreeBSD делает нецелесообразным явное кодирование для каждого из них).

Связанный контент