Como logar acesso a uma pasta específica e mudanças em seu conteúdo?

2

Preciso acompanhar o tempo de acesso à pasta e quero saber quais alterações foram feitas a ele.

Como faço para acionar esses eventos? Existe uma maneira de executar um arquivo .sh específico quando a pasta é aberta?

    
por tvshajeer 17.02.2015 / 07:51

3 respostas

3

Suponho que você precisa saber a hora (do relógio) em que a pasta é aberta, por exemplo, Nautilus , e não o tempo que leva para acessar a pasta.

Usando a lista de janelas

Você pode obter a lista de janelas a partir do comando wmctrl -l e ver se o nome da pasta ocorre na lista. O loop a ser verificado demoraria pelo menos uma fração de segundo para notar que a pasta está aberta.

Você teria wmctrl para ser instalado:

sudo apt-get install wmctrl

No exemplo abaixo, o script é executado um comando quando uma pasta é acessada pela primeira vez, e sai.

Como usar:

  • Cole o script em um arquivo vazio
  • Salvar como access_time.py
  • Alterar na seção principal do script "<command_to_run>" pelo seu comando (entre aspas)
  • Execute-o com o comando:

    python3 </path/to/script> <foldername_without_path>
    

    ou, se você tornou executável:

    </path/to/access_time.py> <foldername_without_path>
    
#!/usr/bin/env python3
import subprocess
import sys
#--- replace "<command_to_run>" with your command (between quotes):
command = "<command_to_run>"
#---
foldername = sys.argv[1]
while True:
    try:
        test = subprocess.check_output(["wmctrl", "-l"]).decode("utf-8")
    except subprocess.CalledProcessError:
        pass
    if foldername in test:
        subprocess.call(["/bin/bash", "-c", command])
        break

Editar

Você pode, no entanto, fazer com que funcione "all-in-one", para que você não precise de outro script. O script abaixo cria um arquivo no diretório $ HOME com a hora em que sua pasta foi acessada.:

#!/usr/bin/env python3
import subprocess
import sys
import os
import time
home = os.environ["HOME"]
foldername = sys.argv[1]

#--- the path your file is saved to (change if you want to, but use full paths)
path = home
#---

while True:
    try:
        test = subprocess.check_output(["wmctrl", "-l"]).decode("utf-8")
    except subprocess.CalledProcessError:
        pass
    if foldername in test:
        with open(path+"/time_data.txt", "a") as out:
            out.write("the folder "+foldername+" was opened "+time.ctime()+"\n")
        break
  • Use como a primeira opção (mas obviamente você não precisa definir o comando)
  • Coloque um ponto antes do nome do arquivo para torná-lo um arquivo oculto (pressione Ctrl + H para alternar visability):

    Se você quiser, mude:

    with open(path+"/time_data.txt", "a") as out:
    

    para:

    with open(path+"/.time_data.txt", "a") as out:
    

    (Cuidado com o recuo!)

Editar 2

De seus comentários, ea discussão no chat, eu entendo que você está realmente procurando uma ferramenta para registrar o acesso a uma pasta (por exemplo, Nautilus) e mudanças no conteúdo do mesmo.
Como uma opção extra, um script de log abrangente que registra em dois segmentos diferentes:

  • Todas as ocasiões em que a pasta foi acessada, por exemplo, nautilus, logado em um arquivo access_log.txt
  • Todas as ocasiões em que a janela da pasta foi fechada, também registrada em access_log.txt
  • Todos os arquivos que foram adicionados (recursivamente) ou removidos do diretório, efetuaram login em um arquivo directory_log.txt

Esses eventos são registrados em dois arquivos diferentes, porque os logs possuem tempos de atualização diferentes. Em tempo real "gravação" do que acontece com um diretório grande com um monte de subdiretórios não é algo que você gostaria de ser feito a cada 5 segundos ou menos. A consequência é que:

  • o acesso log tem (como eu configurei) uma precisão de 0,5 segundos
  • o log do diretório (adicionando / removendo arquivos) tem uma precisão de 10 minutos. Os eventos serão informados dentro de 10 minutos após a ocorrência, com uma precisão de tempo de 10 minutos.

    Eu testei em um diretório (network-) de ~ 800 GB. Se o seu diretório é muito menor, o log-cycle do diretório pode ser (muito) menor também. Eu testei, por exemplo, em um diretório de 20 GB, com um ciclo (log de diretório) de 10 segundos.

Exemplo de saída access_log.txt:

---------------Thu Feb 19 21:01:09 2015---------------
folder opened

---------------Thu Feb 19 21:01:27 2015---------------
folder closed

Exemplo de saída directory_log.txt:

---------------Thu Feb 19 21:14:24 2015---------------
+ /home/jacob/Afbeeldingen/Downloads/2023.pdf
- /home/jacob/Afbeeldingen/Downloads/History-journal
- /home/jacob/Afbeeldingen/Downloads/google-earth-stable_current_i386.deb

O script:

  • Configure como os scripts acima de com uma diferença importante :

    • em vez de usar a pasta nome como argumento , defina a completa caminho + o nome da pasta na cabeça do script (veja o exemplo no script)
  • O comando para executá-lo é:

    python3 /path/to/script.py
    
#!/usr/bin/env python3
import subprocess
import os
import time
import difflib
from threading import Thread
home = os.environ["HOME"]

# The folder to watch:
folder = "/home/jacob/Afbeeldingen"
# the path your log files are saved to (change if you want to, but use full paths):
path = home
#---

for f in os.listdir(path):
    if f.startswith("dr_check_"):
        os.remove(path+"/"+f)

dr_data = path+"/directory_log.txt"
access_data = path+"/access_log.txt"

for f in [dr_data, access_data]:
    if not os.path.exists(f):
        subprocess.Popen(["touch", f])       
foldername = folder.split("/")[-1]

def check_windowlist(foldername):
    while True:
        try:
            if foldername in subprocess.check_output(["wmctrl", "-l"]).decode("utf-8"):
                return "folder opened\n"
            else:
                return "folder closed\n"
            break
        except subprocess.CalledProcessError:
            pass

def check_directory(directory, outfile):
    with open(outfile, "wt") as out:
        for root, dirs, files in os.walk(directory):
            for f in files:
                out.write(root+"/"+f+"\n")

def run_accesscheck():
    while True:
        ch1 = check_windowlist(foldername)
        time.sleep(0.5)
        ch2 = check_windowlist(foldername)
        if ch1 != ch2:
            with open(access_data, "a") as out:
                out.write("-"*15+time.ctime()+"-"*15+"\n"+ch2+"\n")

def run_directorycheck():
    last = 1; outfile_name = "dr_check_"; last_outfile = ""
    while True:
        outfile = path+"/"+outfile_name+str(last)+".txt"
        check_directory(folder, outfile)
        if last != 1:
            changes = []
            diff = difflib.ndiff(
                open(last_outfile).readlines(),
                open(outfile).readlines()
                )
            for item in diff:
                if item.startswith("-") or item.startswith("+"):
                    changes.append(item)
            if len(changes) > 0:
                with open(dr_data, "a") as out:
                    out.write("-"*15+time.ctime()+"-"*15+"\n")
                    for it in sorted(changes):
                        out.write(it)
                    out.write("\n")
            os.remove(last_outfile)       
        last_outfile = outfile; last = last+1
        time.sleep(600)

Thread(target = run_directorycheck).start()
Thread(target = run_accesscheck).start()
    
por Jacob Vlijm 17.02.2015 / 07:58
1

Se você quiser usar o Bash no lugar do Python:

#!/bin/bash
folder=
while true;
do
    command=$(wmctrl -l | grep -o "$folder")
    if [[ "$folder" == "$command" ]];
    then
        ./myscript.sh
        break;
    fi
done

Editar:

Eu alterei um script para que você possa executá-lo com o seguinte comando:

bash folderwatch.sh BackupSSD

Além disso, você pode tornar um script executável para que possa usá-lo sem sh ou bash, porque o shell é definido na primeira linha do script, por exemplo:

chmod u+x folderwatch.sh
./folderwatch.sh BackupSSD
    
por Panta 17.02.2015 / 11:43
0

sudo apt-get incron para instalar o sistema "inotify cron"

link

echo $USER | sudo tee --append /etc/incron.allow para permitir que você jogue o jogo.

icrontab -e para criar um evento para assistir. Abre nano .

Digite o desejo do seu coração. por exemplo,

/home/nodak/watched_dir IN_ACCESS /home/nodak/bin/personal.sh

Salvar e testar.

Mais informações no link

Embora seja simples, e enganosamente, a sintaxe para manobras complicadas não é exatamente a mesma que regular bash, cf, link

    
por Nodak 18.02.2015 / 10:58