Detectando reinício desde a última execução em um script de shell no Linux?

6

Qual é a melhor maneira de contar a partir de um script de shell se o host foi reiniciado desde a última vez que o script foi executado? Posso pensar em armazenar o tempo de atividade em um arquivo em cada execução e verificar se ele diminuiu, mas isso não parece completamente robusto (um servidor pode reiniciar o início rapidamente, armazenar um tempo de atividade baixo e, em seguida, reinicializar lentamente e criar um maior tempo de atividade).

Existe algo como um valor "iniciado em" que teria a garantia de mudar apenas em uma reinicialização? Ou alguma outra boa maneira de detectar um reinício?

    
por kdt 05.04.2011 / 16:48

7 respostas

10

Se você não quiser usar o cron, você também pode criar um diretório em /dev/shm . Como esse local está na memória, sempre estará vazio quando o computador for inicializado. Se não estiver vazio, você não reinicializou.

    
por 05.04.2011 / 20:53
5
  • Crie um diretório em algum lugar quando o sistema for iniciado.
  • Quando o script é executado, se o diretório existir, o sistema foi reiniciado, caso contrário, não.
  • Pegue seu script para remover o diretório.

Use a diretiva @reboot em / etc / crontab para criar o diretório quando o sistema for iniciado. / p>     

por 05.04.2011 / 19:48
2

Outra abordagem seria tocar um arquivo em algum lugar nos scripts de inicialização e procurar por ele no script, o script poderia ser excluído assim que fosse executado na primeira vez.

Apenas tenha cuidado para lidar com mudanças no nível de tempo de execução e assim por diante.

    
por 05.04.2011 / 16:56
2
O comando

sar irá ajudá-lo nisso.

link

    
por 05.04.2011 / 16:53
2

A sysinfo () chamada do sistema operacional lhe dá tempo desde a última reinicialização. É aí que o tempo de atividade obtém os dados antes de executar alguma formatação - é mais simples escrever seu próprio wrapper do que analisar a saída do tempo de atividade / descobrir como ler a hora de início do 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);
}

Você também precisará tocar em um arquivo do seu script e pesquisar seu mtime (usando stat (1) do seu script ou stat (2) do C)

    
por 05.04.2011 / 17:40
0
#!/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
    
por 06.04.2011 / 23:53
0

Isso praticamente chegará lá, isso irá verificar se um arquivo foi acessado desde a última inicialização.

#!/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

Se você executou o arquivo, ele será acessado, mas também pode ter sido editado por alguém e não executado ou talvez tocado.

EDITAR

Um pouco de explicação:

LASTRUN = ls -laru ${FILENAME}|cut -f6,7,8 -d' '|sed 's/'${FILENAME}'//g'|sed 's/^ *//;s/ *$//'

Para o comando acima:

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

Isso deixará uma data / hora pronta para ser convertida em um timestamp unix

LASTBOOT = who -b|sed 's/.*system boot//g'|sed 's/^ *//;s/ *$//'

Para o comando acima:

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

Isso deixará uma data / hora pronta para ser convertida em um timestamp unix

a função unixTimestamp pega a variável Date / TIME e a converte em um timestamp unix e então é apenas um caso de ver qual é o maior número. O número mais alto é o mais recente, então podemos descobrir se a última coisa que aconteceu foi uma reinicialização ou um acesso a arquivos.

    
por 06.04.2011 / 00:59

Tags