我需要跟踪文件夹访问时间,并想知道对其进行了哪些更改。
我如何触发这些事件?有没有办法在打开文件夹时运行特定的 .sh 文件?
答案1
我假设你需要知道文件夹打开的(时钟)时间,例如鹦鹉螺,而不是需要的时间访问该文件夹。
使用窗口列表
您可以从命令中获取窗口列表wmctrl -l
,并查看文件夹的名称是否出现在列表中。但是,检查循环至少需要一瞬间才能注意到文件夹已打开。
您必须wmctrl
安装:
sudo apt-get install wmctrl
在下面的示例中,脚本在第一次访问文件夹时运行一个命令,然后退出。
如何使用:
- 将脚本粘贴到空文件中
- 另存为
access_time.py
"<command_to_run>"
通过命令更改脚本的头部部分(引号之间)使用以下命令运行它:
python3 </path/to/script> <foldername_without_path>
或者,如果你使它可执行:
</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
编辑
但是您可以使其“一体式”运行,这样您就不需要另一个脚本了。下面的脚本会在您的 $HOME 目录中创建一个文件,其中包含访问文件夹的时间。:
#!/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
- 像第一个选项一样使用它(但显然你不需要设置命令)
在文件名前放置一个点可使其成为隐藏文件(按Ctrl+H可切换可见性):
如果您想要这样,请更改:
with open(path+"/time_data.txt", "a") as out:
进入:
with open(path+"/.time_data.txt", "a") as out:
(注意缩进!)
编辑2
从您的评论和聊天中的讨论中,我了解到您实际上正在寻找一种工具来记录对文件夹的访问(例如通过 nautilus)及其内容的更改。
作为额外的选项,一个全面的日志脚本可以在两个不同的线程中记录:
- 所有情况下,文件夹都被 nautilus 等访问过,并记录在文件中
access_log.txt
- 所有文件夹窗口关闭的情况,也登录了
access_log.txt
- 所有添加到(递归)或从目录中删除的文件都记录到文件中
directory_log.txt
这些事件被记录在两个不同的文件中,因为日志的刷新时间不同。实时“记录”一个包含大量子目录的大型目录发生的事情并不是您希望每 5 秒左右完成一次的事情。结果是:
- 这使用权日志的精度为 0.5 秒(我是这样设置的)
这目录log(添加/删除文件)的精度为 10 分钟。事件将在发生后 10 分钟内报告,时间戳精度为 10 分钟。
我在一个约 800 GB 的(网络)目录上进行了测试。如果你的目录小得多,目录log-cycle 也可以 (小得多)。例如,我在 20 GB 的目录上进行了测试,其 (目录日志) 周期为 10 秒。
示例输出access_log.txt:
---------------Thu Feb 19 21:01:09 2015---------------
folder opened
---------------Thu Feb 19 21:01:27 2015---------------
folder closed
示例输出 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
剧本:
按照上面的脚本进行设置但有一个重要的区别:
- 而不是使用文件夹姓名作为争论,设置完整的小路+脚本头部的文件夹名称(参见脚本中的示例)
运行它的命令是:
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()
答案2
如果你想使用 Bash 而不是 Python:
#!/bin/bash
folder=$1
while true;
do
command=$(wmctrl -l | grep -o "$folder")
if [[ "$folder" == "$command" ]];
then
./myscript.sh
break;
fi
done
编辑:
我更改了一个脚本,以便您可以使用以下命令运行它:
bash folderwatch.sh BackupSSD
另外,您可以使脚本可执行,这样您就可以在没有 sh 或 bash 的情况下使用它,因为 shell 是在脚本的第一行定义的,例如:
chmod u+x folderwatch.sh
./folderwatch.sh BackupSSD
答案3
sudo apt-get incron
安装“inotify cron”系统
http://inotify.aiken.cz/?section=incron&page=about&lang=en
echo $USER | sudo tee --append /etc/incron.allow
让您可以玩游戏。
icrontab -e
创建要观看的事件。它将打开nano
。
输入你的内心渴望。例如,
/home/nodak/watched_dir IN_ACCESS /home/nodak/bin/personal.sh
保存并测试。
更多信息来自http://manpages.ubuntu.com/manpages/saucy/man5/incrontab.5.html
虽然它看起来很简单,但复杂动作的语法并不完全相同常规的重击,cf,https://stackoverflow.com/questions/23706194/using-zenity-in-a-root-incron-job-to-display-message-to-currently-logged-in-user