В настоящее время я использую это для отображения текущего времени в моем приглашении bash:
PS1=\[\e[0;32m\]\t \W>\[\e[1;37m\]
20:42:23 ~>
Можно ли отобразить прошедшее время с предыдущего запроса? Такие как:
00:00:00 ~> sleep 10
00:00:10 ~> sleep 20
00:00:20 ~>
Это не имеет ничего общего с. Можно ли периодически менять PS1 скриптом в фоновом режиме?
Ответы:
Один из способов сделать это - использовать функцию bash PROMPT_COMMAND для выполнения кода, модифицирующего PS1. Функция ниже является обновленной версией моего исходного представления; этот использует две переменные окружения меньше и ставит перед ними префикс «_PS1_», чтобы избежать путаницы в существующих переменных.
Поместите это в свой .bash_profile, чтобы все началось.
Обратите внимание, что вы должны набрать довольно быстро, чтобы
sleep
параметр соответствовал параметру приглашения - время на самом деле является разницей между запросами, включая время, необходимое для ввода команды.Позднее добавление:
Основываясь на удаленном ответе @Cyrus, вот версия, которая не загромождает среду дополнительными переменными:
Дополнительное добавление:
Начиная с bash версии 4.2 (
echo $BASH_VERSION
), вы можете избежать внешнихdate
вызовов с помощью новой строки формата printf; заменить$(date +%s)
части с$(printf '%(%s)T' -1)
. Начиная с версии 4.3 , вы можете опустить-1
параметр, чтобы полагаться на поведение «без аргументов значит сейчас ».источник
$SECONDS
он перестает отслеживать время с момента запуска оболочки,$SECONDS
для каждого приглашения может вызвать неожиданное поведение. любая другая функция оболочки, которая может использовать ее по любой причине, связанной с оценкой времени выполнения, будет работать неправильно.Это обрабатывает форматирование вычислением - поэтому, хотя оно расширяется в несколько раз, оно не выполняет никаких подоболочек или каналов.
Он просто обрабатывается
$PS1
как массив и использует более высокие индексы для хранения / вычисления любого / всех необходимых состояний между запросами. Никакое другое состояние оболочки не затрагивается.Я могу немного сломать это, может быть ...
Сначала сохраните текущее значение
$SECONDS
:Затем определите,
$PS1[0]
чтобы быть саморекурсивным таким образом, чтобы всегда устанавливать правильные значения$PS1[1-3]
при одновременной самореференции. Чтобы получить эту часть, вы должны рассмотреть порядок, в котором вычисляются выражения shell-math. Самое главное, что shell-math всегда является последним заказом для shell-math. Прежде всего, оболочка расширяет значения. Таким образом, вы можете ссылаться на старое значение для переменной оболочки в математическом выражении после присвоения его с помощью$
.Вот простой пример:
Оболочка будет оценивать этот оператор, сначала подставляя значение
$x
везде, где используется$
ссылка со знаком доллара, и поэтому выражение становится:... затем оболочка добавляет 5 к значению,
$x
а затем расширяет все выражение доx+10+x
, сохраняя при этом только фактически назначенное значение в ссылочной переменной. Таким образом, расширенное значение математического выражения равно 40, но окончательное значение$x
равно 15.Это в основном то, как
$PS1
работает уравнение, за исключением того, что в индексах массива используется дополнительный уровень математического расширения / оценки.Я не совсем уверен, почему я выбрал использование
PS1[1]=!1
там - я думаю, что это была просто глупая эстетика - но это присваивает 0 для$PS1[1]
расширения при замене параметров. Значение побитового И для 0 и всего остального всегда будет 0, но оно не замыкается накоротко, как логическое значение&&
, когда самый левый первичный элемент равен 0, и поэтому выражение в скобках по-прежнему вычисляется каждый раз. Это важно, конечно, потому что в этом первом элипсисе установлены начальные значения$PS1[2,3]
.В любом случае,
$PS1[1]
здесь гарантируется, что он будет равен 0, даже если он был подделан в промежутках между быстрыми розыгрышами. В скобках есть ......
$PS1[2]
присваивается разность$PS1[3]
и$SECONDS
, и$PS1[3]
присваивается частное этого значения и 3600. Все значения здесь инициализируются. И так:... если в нем хотя бы две цифры,
$PS1[3]
то внутреннее расширение равно нулю, и поскольку мы знаем, что$PS1[1]
это 0, то если$PS1[3]
можно заменить на ничто, то есть, в$PS1[1]
противном случае оно расширяется до своего значения. Таким образом, только однозначные значения для каждой итерации$PS1[3]
назначений будут расширять начальный ноль, и$PS1[3]
он сам расширяется по модулю 60 сразу после этого, при этом одновременно присваивается следующее последовательно меньшее значение для каждого из часов, минут, секунд.Промывайте и повторяйте до последней итерации, когда она
$PS1[3]
будет перезаписана, с текущим значением,$SECONDS
чтобы его можно было сравнить с$SECONDS
еще раз при следующем отображении подсказки.источник
Лучшее решение, которое я нашел до сих пор, это: https://github.com/jichu4n/bash-command-timer
Который печатает
[ 1s011 | May 25 15:33:44 BST ]
или истекшее время на правой стороне после выполненной команды, так что это не загромождает вас PS1.Весь формат строки и времени настраивается. Даже цвет и точность настраиваются. Я знаю, что это может быть немного для минималистов, но это довольно круто.
источник