В bash
специальная переменная $SECONDS
уже увеличивается один раз в секунду, как и в ksh
, откуда исходит функция.
Он инициализируется равным 0 во время запуска оболочки (или значением переменной среды $SECONDS
, если она есть ), но вы также можете установить ее значение вручную.
Однако обратите внимание, что реализация bash
(, в отличие от реализации ksh93, mksh или zsh, последние два имели одинаковую ошибку, но она была исправлена после того, как я сообщил, что )не работает в том, что он увеличивается, когда системные часы проходят точную вторую отметку.
Таким образом, если вы установите значение 0
в 12 :00 :00,1 или 12 :00 :00,9, оно изменится на 1
в 12 :00 :01. (так что на 9/10 секунды позже в первом случае и на 1/10 секунды позже во втором)
Вместо этого вы можете переключиться на zsh, mksh или ksh93.
Затем вам просто нужно использовать $((SECONDS*3))
для чего-то, что увеличивается на 3 каждую секунду, или $((SECONDS/3))
для чего-то, что увеличивается на 1 каждые 3 секунды.
В ksh93
можно было определить дисциплину get
произвольной переменной как$((SECONDS*3))
:
#! /bin/ksh93 -
var.get() {
.sh.value=$((int(SECONDS*3)))
}
SECONDS=0
# testing:
echo "$var"; sleep 1; echo "$var"
дает:
0
3
Еще в ksh93 можно было определить type
переменной, которая будет увеличиваться на любое произвольное число каждую секунду с чем-то вроде:
#! /bin/ksh93 -
SECONDS=0
typeset -T auto_incremented=(
typeset -F start
typeset -i initial=0
typeset -i increment=1
function get {
.sh.value=$((_.initial + int((SECONDS - _.start) * _.increment)))
}
function create {
((_.start = SECONDS))
}
function set {
_.initial=${.sh.value}
((_.start = SECONDS))
}
)
# testing:
auto_incremented var
var.increment=2
echo "$var"; sleep 2; echo "$var"
var=10; echo "$var"; sleep 2; echo "$var"
Что здесь дает:
0
4
10
14
Хотя bash
скопировал довольно много функций из ksh, он не скопировал дисциплины , типы или плавающую точку $SECONDS
.
В bash
один из подходов, который вы можете использовать, — запустить некоторый фоновый процесс, который каждую секунду посылает сигнал на bash
и установить ловушку на этот сигнал, которая обновляет переменную, например:
#! /bin/bash -
var=0 SECONDS=0; trap '((var = SECONDS * 3))' ALRM
ksh93 -c '
t=0 SECONDS=0
while
sleep "$((++t - SECONDS))" && kill -s ALRM -- "$1" 2> /dev/null
do
: nothing
done' ksh "$$" &
# testing:
echo "$var"; sleep 2; echo "$var"
Обратите внимание, что мы не можем просто увеличить $var
в обработчике ловушек, поскольку ловушки обрабатываются только в -между не -встроенными командами, и если одна из этих команд занимает более 1 секунды, в течение которой более посылается один сигнал SIGALRM, обрабатывается только один.
Здесь мы используем встроенный скрипт ksh93
для отправки сигнала каждую секунду, но вместо этого вы можете использовать zsh
, perl
, python
..., если они доступны.
Вы можете восстановить права и владельца пакетов по умолчанию.
Зациклите приведенную выше команду, чтобы получить имя пакета для каждого предоставленного файла в каталоге /usr/bin.:
yum whatprovides /usr/bin
А затем снова выполните приведенные выше команды, заменив пакеты на пакеты, полученные из последней команды:
rpm --setugids <package>
rpm --setperms <package>
Это должно быть в правильном порядке.