Назад | Перейти на главную страницу

Обнаружение перезагрузки с момента последнего запуска в сценарии оболочки в Linux?

Как лучше всего узнать из сценария оболочки, был ли хост перезагружен с момента последнего запуска сценария? Я могу подумать о том, чтобы сохранять время безотказной работы в файле при каждом запуске и проверять, уменьшилось ли оно, но это не кажется полностью надежным (сервер может перезапуститься быстро, сохранить низкое время безотказной работы, затем медленно перезагрузиться и придумать более высокое время безотказной работы).

Есть ли что-то вроде значения «началось с», которое гарантированно изменится только при перезагрузке? Или какой-нибудь другой хороший способ обнаружения перезапуска?

Если вы не хотите использовать cron, вы также можете создать каталог в /dev/shm. Поскольку это место находится в памяти, оно всегда будет пустым при запуске компьютера. Если он не пустой, вы не перезагружались.

  • Создайте каталог где-нибудь при запуске системы.
  • Когда ваш скрипт запускается, если каталог существует, то система перезагружается, иначе нет.
  • Получите ваш скрипт для удаления каталога.

Использовать @reboot директива в / etc /crontab для создания каталога при запуске системы.

Другой подход - прикоснуться к файлу где-нибудь в сценариях запуска и найти его в сценарии, после чего сценарий может удалить его после первого запуска.

Просто будьте осторожны, вы хорошо справляетесь с изменениями уровня исполнения и так далее.

sar Команда поможет вам в этом.

http://linux.die.net/man/1/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, а затем просто показывает, какое число больше. Более высокое число является самым последним, поэтому мы можем определить, было ли последнее, что произошло, - это перезагрузка или доступ к файлу.