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

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

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

7 ответов

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

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

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

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

http://linux.die.net/man/1/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
Другие вопросы по тегам