J'ai besoin de suivre le temps d'accès au dossier et je veux savoir quelles modifications y sont apportées.
Comment déclencher ces événements? Existe-t-il un moyen d'exécuter un fichier .sh spécifique lorsque le dossier est ouvert?
Je suppose que vous devez connaître l'heure (d'horloge) d'ouverture du dossier, par ex. nautilus , pas le temps nécessaire pour accéder au dossier.
Vous pouvez obtenir la liste des fenêtres à partir de la commande wmctrl -l
, et voyez si le nom du dossier apparaît dans la liste. La boucle à vérifier prendrait cependant au moins une fraction de seconde pour remarquer que le dossier est ouvert.
Vous auriez wmctrl
à installer:
Sudo apt-get install wmctrl
Dans l'exemple ci-dessous, le script exécute une commande lorsqu'un dossier est accédé pour la première fois et se ferme.
Comment utiliser:
access_time.py
"<command_to_run>"
par votre commande (entre guillemets)Exécutez-le soit avec la commande:
python3 </path/to/script> <foldername_without_path>
ou, si vous l'avez rendu exécutable:
</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
Vous pouvez cependant le faire fonctionner "tout-en-un", vous n'avez donc pas besoin d'un autre script. Le script ci-dessous crée un fichier dans votre répertoire $ HOME avec l'heure à laquelle votre dossier a été accédé .:
#!/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
Placez un point avant le nom de fichier pour en faire un fichier caché (appuyez sur Ctrl+H pour basculer la visibilité):
Si vous le souhaitez, changez:
with open(path+"/time_data.txt", "a") as out:
dans:
with open(path+"/.time_data.txt", "a") as out:
(Attention au tiret!)
D'après vos commentaires et la discussion dans le chat, je comprends que vous recherchez en fait un outil pour enregistrer l'accès à un dossier (par exemple par nautilus) et les modifications du contenu de celui-ci.
En option supplémentaire, un script de journal complet qui enregistre dans deux threads différents:
access_log.txt
access_log.txt
directory_log.txt
Ces événements sont enregistrés dans deux fichiers différents, car les journaux ont des temps d'actualisation différents. L'enregistrement en temps réel de ce qui arrive à un grand répertoire avec beaucoup de sous-répertoires n'est pas quelque chose que vous voudriez faire toutes les 5 secondes environ. La conséquence est que:
le journal du répertoire (ajout/suppression de fichiers) a une précision de 10 minutes. Les événements seront signalés dans les 10 minutes suivant leur déroulement, avec une précision d'horodatage de 10 minutes.
Je l'ai testé sur un répertoire (réseau) de ~ 800 Go. Si votre répertoire est beaucoup plus petit, le cycle de journalisation du répertoire peut également être (beaucoup) plus petit. Je l'ai testé par exemple sur un répertoire de 20 Go, avec un cycle (journal de répertoire) de 10 secondes.
Exemple de sortie access_log.txt:
---------------Thu Feb 19 21:01:09 2015---------------
folder opened
---------------Thu Feb 19 21:01:27 2015---------------
folder closed
Exemple de sortie 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
Configurez-le comme les scripts ci-dessus avec une différence importante:
La commande pour l'exécuter est alors:
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()
Si vous souhaitez utiliser Bash à la place de Python:
#!/bin/bash
folder=$1
while true;
do
command=$(wmctrl -l | grep -o "$folder")
if [[ "$folder" == "$command" ]];
then
./myscript.sh
break;
fi
done
Éditer:
J'ai changé un script pour que vous puissiez l'exécuter avec la commande suivante:
bash folderwatch.sh BackupSSD
En outre, vous pouvez rendre un script exécutable afin de pouvoir l'utiliser sans sh ni bash, car le shell est défini dans la première ligne du script, par exemple:
chmod u+x folderwatch.sh
./folderwatch.sh BackupSSD
Sudo apt-get incron
pour installer le système "inotify cron"
http://inotify.aiken.cz/?section=incron&page=about&lang=en
echo $USER | Sudo tee --append /etc/incron.allow
pour vous permettre de jouer au jeu.
icrontab -e
pour créer un événement à regarder. Il ouvre nano
.
Entrez le désir de votre cœur. par exemple.,
/home/nodak/watched_dir IN_ACCESS /home/nodak/bin/personal.sh
Enregistrez et testez.
Plus d'informations sur http://manpages.ubuntu.com/manpages/saucy/man5/incrontab.5.html
Bien qu'elle soit simple et trompeuse, la syntaxe des manœuvres compliquées n'est pas tout à fait la même que régulière bash, cf, https://stackoverflow.com/questions/23706194/using-zenity-in-a-root-incron-job-to-display-message-to-currently-logged-in-user