время в командной строке bash не изменяется с течением времени

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

Я изменил приглашение в моем .bashrc, чтобы оно показывало текущее время. Это было оригинальное приглашение (из свежей установки MX Linux)

PS1="$PURPLE\u$nc@$CYAN\H$nc:$GREEN\w$nc\\n$GREEN\$$nc "

и я изменил его на это

PS1="$PURPLE\u$nc@$CYAN\H$nc $YELLOW$(date '+%Y-%m-%d %H:%M:%S')$nc $REEN\w$nc\\n$GREEN\$$nc "

Когда я открываю терминал, я вижу текущую дату и время в приглашении. Новые приглашения не отображаются с временем, когда они генерируются. Они всегда показывают то же время, что и первое приглашение. Что я делаю не так?

enter image description here

Внутри двойных кавычек разворачивания происходят в момент оценки, что означает, что date выполняется, когда PS1 присваивается — это приводит к результату, который вы видите, где дата и время сохраняются изначально и никогда не обновляются.

Вам нужно использовать одинарные кавычки вокруг подстановки date, чтобы она оценивалась каждый раз, когда показывается приглашение:

PS1="$PURPLE\u$nc@$CYAN\H$nc $YELLOW"'$(date "+%Y-%m-%d %H:%M:%S")'"$nc $GREEN\w$nc\\n$GREEN\$$nc "

Вместо того чтобы вызывать date вручную, вы также можете использовать встроенную поддержку дат в запросах оболочки: \d заменяется на дату в формате “день недели месяц дата”, а \D{формат} заменяется на дату в заданном формате, с тем же синтаксисом, что и вы использовали (синтаксис strftime). Таким образом:

PS1="$PURPLE\u$nc@$CYAN\H$nc $YELLOW\\D{%Y-%m-%d %H:%M:%S}$nc $GREEN\w$nc\\n$GREEN\$$nc "

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

См. Управление приглашением в руководстве bash для подробной информации.

Другой вариант … экранируйте $ в $(date ...), чтобы избежать выполнения вызова date при определении PS1; новое определение выглядит так:

PS1="$PURPLE\u$nc@$CYAN\H$nc $YELLOW\$(date '+%Y-%m-%d %H:%M:%S')$nc $REEN\w$nc\\n$GREEN\$$nc "
                                    ^-------- экранировать $

.

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

Вопрос, с которым вы столкнулись, связан с отображением времени в командной строке Bash. Основная проблема заключается в том, что время не обновляется динамически при каждом вызове командной строки, а остается одинаковым с момента первого отображения. Эта ситуация требует понимания, как Bash обрабатывает подстановки в переменной PS1.

Теория

Переменная PS1 отвечает за внешний вид приглашения командной строки Hашелла. Она поддерживает подстановки, которые позволяют динамически изменять ее содержимое. Когда вы обернули команду date в $(...) внутри двойных кавычек, оболочка Bash выполняет эту команду сразу же при назначении переменной, и полученное значение сохраняется. Это означает, что значение времени фиксируется и не меняется, пока вы не перезапустите сессию или не выполните команду source ~/.bashrc.

Двойные кавычки позволяют Bash немедленно вычислять подстановки. Однако это не всегда желаемое поведение, особенно когда вам нужно обновлять динамическое содержимое, такое как время. Чтобы добиться обновления времени при каждом показе приглашения, нужно использовать одинарные кавычки или экранировать символ $ с целью отложенного вычисления подстановки.

Пример

Рассмотрим различные способы решения проблемы:

  1. Использование одинарных кавычек:
PS1="$PURPLE\u$nc@$CYAN\H$nc $YELLOW"'$(date "+%Y-%m-%d %H:%M:%S")'"$nc $GREEN\w$nc\\n$GREEN\$$nc "

Использование одинарных кавычек вокруг команды date позволяет отложить ее выполнение до момента отображения командной строки. Это решение встроит команду в саму строку и будет выполнять ее каждый раз, когда вы вызываете новую командную строку.

  1. Экранирование символа $:
PS1="$PURPLE\u$nc@$CYAN\H$nc $YELLOW\$(date '+%Y-%m-%d %H:%M:%S')$nc $GREEN\w$nc\\n$GREEN\$$nc "

Здесь экранирование символа $ перед подстановкой $(...) предотвращает немедленное выполнение команды date при назначении переменной PS1. Это решение обеспечивает обновление времени при каждом выводе командной строки.

  1. Использование встроенных возможностей Bash:

Bash поддерживает подстановки для дат прямо в приглашении. Можно использовать:

PS1="$PURPLE\u$nc@$CYAN\H$nc $YELLOW\\D{%Y-%m-%d %H:%M:%S}$nc $GREEN\w$nc\\n$GREEN\$$nc "

Здесь \D{...} использует функции форматирования времени, аналогичные strftime, для динамической генерации даты и времени без необходимости вызывать команду date.

Применение

Выбор подходящего метода зависит от ваших предпочтений. Если вы хотите минимизировать количество вычислений при каждом отображении командной строки и достигнуть наибольшей эффективности, стоит использовать встроенные возможности Bash (\D{}). Это решение будет оптимальным с точки зрения производительности, хотя преимущества незначительны для современных систем.

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

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

Таким образом, проблема, с которой вы столкнулись, не связана с ошибкой, а вызвана особенностью обработки подстановок в Bash. Выбор решения зависит от вашего сценария использования и предпочтений. Все указанные методы одинаково надежны, и следуя им, вы получите динамически обновляемое время в вашей командной строке.

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

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