PS1[3]=$SECONDS
PS1='${PS1[!(PS1[1]=!1&(PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600))
]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]/60%60), ${PS1[3]})):${PS1[1
]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]%60), ${PS1[3]})):${PS1[1
]#${PS1[3]%%*??}0}$((PS1[3]=(SECONDS), ${PS1[3]})):'$PS1
Это обрабатывает форматирование вычислением - поэтому, хотя оно расширяется в несколько раз, оно не выполняет никаких подоболочек или каналов.
Он просто обрабатывается $PS1
как массив и использует более высокие индексы для хранения / вычисления любого / всех необходимых состояний между запросами. Никакое другое состояние оболочки не затрагивается.
00:00:46:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:00:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:43:[mikeserv@desktop tmp]$ sleep 10
00:00:33:[mikeserv@desktop tmp]$ sleep 10
00:00:15:[mikeserv@desktop tmp]$
00:00:15:[mikeserv@desktop tmp]$
00:00:02:[mikeserv@desktop tmp]$
00:02:27:[mikeserv@desktop tmp]$
Я могу немного сломать это, может быть ...
Сначала сохраните текущее значение $SECONDS
:
PS1[3]=$SECONDS
Затем определите, $PS1[0]
чтобы быть саморекурсивным таким образом, чтобы всегда устанавливать правильные значения $PS1[1-3]
при одновременной самореференции. Чтобы получить эту часть, вы должны рассмотреть порядок, в котором вычисляются выражения shell-math. Самое главное, что shell-math всегда является последним заказом для shell-math. Прежде всего, оболочка расширяет значения. Таким образом, вы можете ссылаться на старое значение для переменной оболочки в математическом выражении после присвоения его с помощью $
.
Вот простой пример:
x=10; echo "$(((x+=5)+$x+x))" "$x"
40 15
Оболочка будет оценивать этот оператор, сначала подставляя значение $x
везде, где используется $
ссылка со знаком доллара, и поэтому выражение становится:
(x+=5)+10+x
... затем оболочка добавляет 5 к значению, $x
а затем расширяет все выражение до x+10+x
, сохраняя при этом только фактически назначенное значение в ссылочной переменной. Таким образом, расширенное значение математического выражения равно 40, но окончательное значение $x
равно 15.
Это в основном то, как $PS1
работает уравнение, за исключением того, что в индексах массива используется дополнительный уровень математического расширения / оценки.
PS1='${PS1[!(PS1[1]=!1&(...))]#...}...'
Я не совсем уверен, почему я выбрал использование PS1[1]=!1
там - я думаю, что это была просто глупая эстетика - но это присваивает 0 для $PS1[1]
расширения при замене параметров. Значение побитового И для 0 и всего остального всегда будет 0, но оно не замыкается накоротко, как логическое значение &&
, когда самый левый первичный элемент равен 0, и поэтому выражение в скобках по-прежнему вычисляется каждый раз. Это важно, конечно, потому что в этом первом элипсисе установлены начальные значения $PS1[2,3]
.
В любом случае, $PS1[1]
здесь гарантируется, что он будет равен 0, даже если он был подделан в промежутках между быстрыми розыгрышами. В скобках есть ...
PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600
... $PS1[2]
присваивается разность $PS1[3]
и $SECONDS
, и $PS1[3]
присваивается частное этого значения и 3600. Все значения здесь инициализируются. И так:
${PS1[1]#${PS1[3]%%*??}0}
... если в нем хотя бы две цифры, $PS1[3]
то внутреннее расширение равно нулю, и поскольку мы знаем, что $PS1[1]
это 0, то если $PS1[3]
можно заменить на ничто, то есть, в $PS1[1]
противном случае оно расширяется до своего значения. Таким образом, только однозначные значения для каждой итерации $PS1[3]
назначений будут расширять начальный ноль, и $PS1[3]
он сам расширяется по модулю 60 сразу после этого, при этом одновременно присваивается следующее последовательно меньшее значение для каждого из часов, минут, секунд.
Промывайте и повторяйте до последней итерации, когда она $PS1[3]
будет перезаписана, с текущим значением, $SECONDS
чтобы его можно было сравнить с $SECONDS
еще раз при следующем отображении подсказки.