Установка переменной $USERNAME в zsh не имеет эффекта.

Вопрос или проблема

Установка переменной USERNAME в zsh не имеет эффекта. Обращение к переменной всегда возвращает текущего вошедшего пользователя.

james@localhost:~$ USERNAME=foo
james@localhost:~$ echo $USERNAME
james

Я не смог найти ссылок или документации, которые объясняют это поведение. Похоже, что $USERNAME – это своего рода специальная переменная. Есть ли другие? Где это задокументировано или объяснено?

Похоже, вы используете Z Shell, по крайней мере, описанное вами поведение воспроизводимо там:

zsh$ echo $USERNAME
user1
zsh$ USERNAME=test
zsh$ echo $USERNAME
user1
zsh$ 

В мануале zshparam дается причина:

USERNAME
Имя пользователя, соответствующее реальному идентификатору пользователя процесса оболочки. Если у вас достаточно полномочий, вы можете изменить имя пользователя (а также идентификатор пользователя и идентификатор группы) оболочки, присвоив это параметру.
Также (при наличии достаточных полномочий) вы можете запустить одну команду под другим именем пользователя (а также идентификатором пользователя и идентификатором группы), используя ‘(USERNAME=username; command)’.

Таким образом, при достаточных полномочиях, например, как root, это работает, но только если user1 является действительным именем пользователя:

su
zsh# echo $USERNAME
root
zsh# USERNAME=user1
zsh# echo $USERNAME
user1
zsh# id
uid=1001(user1) gid=1000(users)   
groups=1000(users),...

Да, есть и другие специальные переменные, обратите внимание на маркировку <S> в man zshparam, чтобы упомянуть лишь несколько примеров:

  • $? код завершения, возвращаемый последней командой
  • $$ идентификатор процесса этой оболочки
  • $EGID эффективный идентификатор группы процесса оболочки
  • $SECONDS количество секунд с момента вызова оболочки

Переменные USER и LOGNAME рассматриваются в мануале environ(7). login(1) — это процесс, который устанавливает эти переменные.

Переменные USER и LOGNAME могут быть изменены, и последующий доступ возвращает новое значение.

Нигде не нашел ссылки для USERNAME, и эта переменная не установлена в bash 4.3. Bash определяет UID как переменную только для чтения. Попытка изменить эту переменную в bash не удалась.

linux manpage говорит, что USER “используется некоторыми программами, основанными на BSD”, в то время как LOGNAME “используется некоторыми программами, основанными на System-V”, а apple manpage утверждает, что USER устарел.

Ответ или решение

Установка переменной USERNAME в оболочке Zsh не оказывает эффекта, так как эта переменная является специальной и связана с идентификатором пользователя, который запустил оболочку. Давайте рассмотрим эту проблему более подробно.

Пояснение поведения переменной USERNAME

Когда вы задаете значение переменной USERNAME, как в вашем примере:

USERNAME=foo
echo $USERNAME

Вы получаете james, потому что переменная USERNAME в Zsh автоматически связывается с фактическим именем пользователя, который запустил текущую оболочку. Это поведение зафиксировано в документации, где указано, что USERNAME соответствует имени пользователя, соответствующему реальному идентификатору пользователя процесса оболочки.

Цитата из документации

В соответствии с мануалом zshparam:

USERNAME: Имя пользователя, соответствующее реальному идентификатору пользователя процесса оболочки. При наличии достаточных привилегий вы можете изменить имя пользователя (а также идентификатор пользователя и группу) оболочки, присвоив это значение.

Это означает, что в обычном режиме, без соответствующих привилегий (например, в качестве пользователя root), вы не сможете изменить значение USERNAME.

Пример с повышенными привилегиями

Если вы получите доступ к оболочке от имени пользователя с достаточными правами (например, root), вы сможете изменить USERNAME:

su
echo $USERNAME
root
USERNAME=user1
echo $USERNAME
user1
id

Здесь id показывает, что идентификатор пользователя изменился на user1, так как мы используем root.

Другие специальные переменные

Существуют и другие специальные переменные в Zsh, которые имеют фиксированные значения. Они отмечены знаком <S> в документации. Примеры таких переменных:

  • $? — статус завершения последней команды.
  • $$ — идентификатор процесса текущей оболочки.
  • $EGID — эффективный идентификатор группы процесса оболочки.
  • $SECONDS — количество секунд с момента запуска оболочки.

Переменные USER и LOGNAME

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

Документация по этим переменным можно найти в environ(7). Процесс login(1) устанавливает эти переменные при входе в систему.

Заключение

Таким образом, переменная USERNAME в Zsh играет особую роль и не подлежит изменению в обычных условиях. Если требуется управлять переменными пользователя, возможно, стоит обратить внимание на использование USER и LOGNAME, которые более гибкие в этом отношении.

Оцените материал
Добавить комментарий

Капча загружается...