Bash Script - Como verificar alterações no arquivo de texto

0

Primeiro de tudo, eu sou bem inexperiente nisso, mas eu preciso de um script especial para um dos meus servidores de jogos. O script bash deve simplesmente determinar se um documento de texto específico recebe mudanças periodicamente em seu conteúdo ou não.

Se houver algum tipo de alteração dentro de 30 segundos, o script deve fazer:

echo "text file content is changing"

Se não houver nenhum tipo de alteração dentro de 30 segundos, o script deverá:

echo "text file content is not changing"

Após o script bash determinar que o conteúdo muda, ele deve se repetir continuamente.

EDIT: Obrigado por toda sua ajuda pessoal! Eu tenho outra preocupação, é possível que o script esteja determinando automaticamente o arquivo de texto criado / editado mais recente em uma pasta específica? Isso significa que, mesmo que um novo arquivo de texto tenha sido criado nessa pasta enquanto o script estiver determinando o arquivo de texto anterior, ele deverá cancelar o processo e determinar o novo (mais recente) arquivo.

Obrigado antecipadamente! : -)

    
por Phillip 13.04.2017 / 03:19

2 respostas

2

Eu uso /usr/bin/stat --format='%Y' no meu arquivo de configuração e faço uma cópia privada sempre que "%Y time of last data modification, seconds since Epoch "é alterado. Dessa forma, eu não preciso ler o arquivo inteiro apenas para verificar a hora da modificação.

Fragmentos de código não verificáveis:

original=""                     # set the <config.file>
original_update=0               # time <config.file> was last modified
config="/var/tmp/${me}.$$.config" # my writable copy of config

...

function up-to-date () {
    # updates configuration file if necessary
    new_update="$(/usr/bin/stat --format='%Y' $original )"
    if [[  "$new_update" -ne "$original_update" ]] ; then
        if [[ $(countconfiglines "$original") -eq 0  ]] ; then
            echo "Invalid configuration in $original" >&2
            exit 4
        else
            /bin/cp --force "$original" "$config"
            original_update="$new_update"
        fi
    fi
    }

... 


else
    # watch for changes, record "%Y time of last modification,
    # seconds since Epoch"
    original_update="$(/usr/bin/stat --format='%Y' $original )"

    # make a writeable copy for our use, and clean it up at the end
    # unless $debug
    [[ $debug -ne 0 ]] || trap "/bin/rm -f $config" EXIT
    /bin/cp --force "$original" "$config"

fi

E eu chamo up-to-date todas as vezes em torno do meu loop principal, quando estou disposto a analisar um novo arquivo de configuração.

    
por waltinator 13.04.2017 / 09:21
0

Assistindo a arquivos individuais

Use as somas de verificação de arquivos. Aqui está um exemplo de script que o ajudaria.

#!/bin/bash

# do not put tabs before paths for second file through last file
files_to_check="/path/to/first/file
/path/to/second/file
/path/to/.../file"

delay=30

while true
do
    while read path
    do
        [ ! -e "$path.sha256" ] && sha256sum "$path" > "$path.sha256"
        status=$(sha256sum --quiet -c "$path.sha256"  > /dev/null 2>&1 && echo "No change!" || (echo "File changed!" && sha256sum "$path" > "$path.sha256"))
        [ "$status" == "No change!" ] && color="\e[0m" || color="\e[38;5;208m"
        printf "$color[%s] %s: %s\e[0m\n" $(date +%Y%m%d.%H%M%S) "$path" "$status"
    done <<< "$files_to_check"
    sleep $delay
    echo "-----------"
done

Se você quiser apenas verificar um diretório inteiro de forma recursiva, poderá passar a saída de find /dir/to/check -type f para o loop while em vez da lista de arquivos.

A saída do script acima é semelhante a esta

[20170413.095401] a: No change!
[20170413.095401] b: No change!
-----------
[20170413.095431] a: No change!
[20170413.095431] b: No change!
-----------
[20170413.095501] a: File changed!
[20170413.095501] b: No change!

Verificando um diretório inteiro e observando a adição / exclusão / modificação de arquivos

Esse script varrerá um diretório inteiro a cada 30 segundos (sem incluir o tempo necessário para executar a varredura) e as adições de cor (verde), remoções (vermelho) e alterações (laranja).

#!/bin/bash

# do not put tabs before paths for second file through last file
dir_to_check="/path/to/directory"
delay=30

# please note that the time it takes to generate checksums will produce more time
# between loops than the actual delay
while true
do
    while read path
    do
        [ ! -e "${path/.sha256/}" ] && printf "\e[38;5;196m%s\e[0m\n" "[$(date +%Y%m%d.%H%M%S)] File removed: ${path/.sha256/}" && rm "$path"
    done <<< "$(find $dir_to_check -type f -iname "*\.sha256" | sort)"

    while read path
    do
        if [ ! -e "$path.sha256" ]; then
            printf "\e[38;5;046m%s\e[0m\n" "[$(date +%Y%m%d.%H%M%S)] New file found: $path (modified $(date --date="@$(stat --format="%Y" "$path")" +%Y%m%d.%H%M%S))"
            sha256sum "$path" > "$path.sha256"
        else
            status=$(sha256sum --quiet -c "$path.sha256"  > /dev/null 2>&1 && echo "No change!" || (echo "File changed! ($(date --date="@$(stat --format="%Y" "$path")" +%Y%m%d.%H%M%S))" && sha256sum "$path" > "$path.sha256"))
            [ "$status" == "No change!" ] && color="\e[0m" || color="\e[38;5;208m"
            printf "$color[%s] %s: %s\e[0m\n" $(date +%Y%m%d.%H%M%S) "$path" "$status"
        fi
    done <<< "$(find $dir_to_check -type f ! -iname "*\.sha256" | sort)"
    sleep $delay
    echo "-----------"
done

A saída se parece com (desculpe, a cor não é transferida aqui)

[20170414.103126] /tmp/change/a: No change!
[20170414.103126] /tmp/change/b: No change!
[20170414.103126] /tmp/change/c: No change!
[20170414.103126] /tmp/change/run.sh: File changed! (20170414.103125)
-----------

    ...

-----------
[20170414.103156] File removed: /tmp/change/a
[20170414.103156] /tmp/change/b: No change!
[20170414.103156] /tmp/change/c: No change!
[20170414.103156] /tmp/change/run.sh: No change!
-----------
[20170414.103206] New file found: /tmp/change/a (modified 20170414.103200)
[20170414.103206] /tmp/change/b: No change!
[20170414.103206] /tmp/change/c: No change!
[20170414.103206] /tmp/change/run.sh: No change!
    
por b_laoshi 13.04.2017 / 03:53