Обнаружение перезапуска с момента последнего запуска сценария оболочки в Linux?
Как лучше всего определить из сценария оболочки, если хост был перезапущен с момента последнего запуска сценария? Я могу подумать о том, чтобы хранить время работы в файле при каждом запуске и проверять, уменьшилось ли оно, но это не кажется полностью надежным (сервер может быстро перезапуститься, сохранить малое время безотказной работы, затем медленно перезагрузиться и получить выше время работы).
Есть ли что-то вроде "началось с" значения, которое гарантированно изменится только при перезагрузке? Или какой-то другой хороший способ обнаружения перезапуска?
7 ответов
Если вы не хотите использовать cron, вы также можете создать каталог в /dev/shm
, Поскольку это место находится в памяти, оно всегда будет пустым при запуске компьютера. Если он не пустой, вы не перезагрузились.
- Создайте каталог где-нибудь при запуске системы.
- Когда ваш скрипт запускается, если каталог существует, система перезапускается, иначе нет.
- Получите ваш скрипт для удаления каталога.
Использовать @reboot
директива в / etc / crontab для создания каталога при запуске системы.
sar
Команда поможет вам в этом.
Другой подход заключается в том, чтобы прикоснуться к файлу где-нибудь в сценариях запуска и найти его в сценарии. Затем сценарий может быть удален при первом запуске.
Просто будьте осторожны, вы справляетесь с изменениями уровня времени выполнения и так далее.
Вызов ОС sysinfo() дает вам время с момента последней перезагрузки. Именно здесь uptime получает данные перед выполнением некоторого форматирования - проще написать свою собственную обертку вокруг этого, чем анализировать вывод uptime / определять, как читать время запуска init (pid 1).
#include <stdio.h>
#include <time.h>
#include <errno.h>
int main(int argc, char **argv)
{
struct sysinfo info;
int status;
status=sysinfo(&info);
if (status==0) {
printf("%d\n", info.uptime);
} else {
fprintf(STDERR,"error %d occurred\n", errno);
}
exit (status);
}
Вам также нужно будет дотронуться до файла из вашего скрипта и опросить его mtime (используя stat(1) из вашего скрипта или stat(2) из C)
Это фактически доставит вас туда, это проверит, был ли файл доступен с момента последней загрузки.
#!/bin/bash
unixTimestamp () {
date --utc --date "$1" +%s
}
if [ "$1" == "" ];then
echo "You must specify a filename (e.g. './lastRun.sh foobar.sh')"
exit 255
fi
FILENAME=$1
if [ -f ${FILENAME} ]; then
if [ -n ${FILENAME} ]; then
LASTRUN=`ls -laru ${FILENAME}|cut -f6,7,8 -d' '|sed 's/'${FILENAME}'//g'|sed 's/^ *//;s/ *$//'`
LASTBOOT=`who -b|sed 's/.*system boot//g'|sed 's/^ *//;s/ *$//'`
echo "Last Run: '${LASTRUN}'"
echo "Last Boot: '${LASTBOOT}'"
if [ "$(unixTimestamp ${LASTRUN})" -lt "$(unixTimestamp ${LASTBOOT})" ]; then
echo "${FILENAME} has not been run since last boot."
exit 1
else
echo "${FILENAME} has been run since last boot"
exit 0
fi
fi
else
echo "Unable to find file '${FILENAME}'..."
exit 255
fi
Если вы запустили файл, к нему будет получен доступ, но он также может быть отредактирован кем-то и не запущен, или, возможно, затронут.
РЕДАКТИРОВАТЬ
Немного объяснения:
LASTRUN =ls -laru ${FILENAME}|cut -f6,7,8 -d' '|sed 's/'${FILENAME}'//g'|sed 's/^ *//;s/ *$//'
Для приведенной выше команды:
ls -laru ${FILENAME}|cut -f6,7,8 -d' ' # Will take the filename and display the last access time
|sed 's/'${FILENAME}'//g' # Will strip the filename out to leave you with the date and time
|sed 's/^ *//;s/ *$//' # Will strip out whitespace before and after the date/time
Это даст вам дату и время, готовые для преобразования в метку времени Unix.
LASTBOOT=who -b|sed 's/.*system boot//g'|sed 's/^ *//;s/ *$//'
Для приведенной выше команды:
who -b # Will show the time the system last booted
|sed 's/.*system boot//g' # Will strip out the text "system boot" to leave you with a date/time
|sed 's/^ *//;s/ *$//' # Will strip out whitespace before and after the date/time
Это даст вам дату и время, готовые для преобразования в метку времени Unix.
функция unixTimestamp берет переменную Date/TIME и преобразует ее в метку времени unix, а затем это просто случай, чтобы увидеть, какое число больше. Более высокое число - самое последнее, поэтому мы можем определить, была ли последняя перезагрузка или доступ к файлу.
#!/bin/bash
#
# usage: $(basename $0) FILE
# returns TRUE if the file has been run since last boot
#
[[ $# -ne 1 ]] && { grep 'usage' "$0"; exit 255; }
# access time of script/program
atime="$(stat -c %X "$1")"
# Last boot as unix timestamp
btime="$(date -d "$(who -b | awk '{ print $3, $4 }')" +%s)"
if [[ $atime -gt $btime ]]; then
exit 0 # true
else
exit 1 # false
fi