Как лучше всего узнать из сценария оболочки, был ли хост перезагружен с момента последнего запуска сценария? Я могу подумать о том, чтобы сохранять время безотказной работы в файле при каждом запуске и проверять, уменьшилось ли оно, но это не кажется полностью надежным (сервер может перезапуститься быстро, сохранить низкое время безотказной работы, затем медленно перезагрузиться и придумать более высокое время безотказной работы).
Есть ли что-то вроде значения «началось с», которое гарантированно изменится только при перезагрузке? Или какой-нибудь другой хороший способ обнаружения перезапуска?
Если вы не хотите использовать cron, вы также можете создать каталог в /dev/shm
. Поскольку это место находится в памяти, оно всегда будет пустым при запуске компьютера. Если он не пустой, вы не перезагружались.
Использовать @reboot
директива в / etc /crontab для создания каталога при запуске системы.
Другой подход - прикоснуться к файлу где-нибудь в сценариях запуска и найти его в сценарии, после чего сценарий может удалить его после первого запуска.
Просто будьте осторожны, вы хорошо справляетесь с изменениями уровня исполнения и так далее.
sar
Команда поможет вам в этом.
В sysinfo() Вызов ОС показывает время с момента последней перезагрузки. Именно здесь время безотказной работы получает данные перед выполнением некоторого форматирования - проще написать собственную оболочку вокруг этого, чем анализировать вывод времени безотказной работы / выяснять, как читать время начала инициализации (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 (используя стат (1) из вашего сценария или стат (2) из C)
#!/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
Это практически доставит вас туда, это проверит, был ли доступ к файлу с момента последней загрузки.
#!/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, а затем просто показывает, какое число больше. Более высокое число является самым последним, поэтому мы можем определить, было ли последнее, что произошло, - это перезагрузка или доступ к файлу.