如果重要的话,这个问题与 Xubuntu 22.04 相关。不过,这可能是一个常见的 Unix 问题。
在 shell 脚本中,我首先要创建一个参考文件,例如
echo $(date) > ~/reference.file
然后我想启动一些应用程序直到其工作流程中的某个步骤。我想知道,到目前为止应用程序访问了哪些文件。
然后我想继续使用第一个提到的 shell 脚本(或另一个脚本)find
来显示所有已访问或修改的文件。当然,我想忽略/sys
或中出现的所有情况/proc
,因为它们的数量可能令人难以置信。我尝试过类似的东西
find ${WO} -type d \( -path /sys -o -path /proc \) \
-prune -o -name '*' \
-newerac ~/reference.file \
-type f \
-printf "%TY-%Tm-%TdT%TT %p\n" 2>/dev/null | \
sort -r | \
ssed -R 's/^([^.]+)\.\d+ (.*)$/\1 \2/'
我通过发出命令来测试它
cat /tmp/test
echo $(date) > /tmp/test2
然后是find
上面提到的命令。在来自并行进程的其他文件中,它只找到了/tmp/test2
(被第二个命令修改的文件),但没有找到/tmp/test
仅由该命令列出的文件cat
。据我了解,列出是一种访问,应该被 捕获-newerac ~/reference.file
。
我应该在 find 命令中更改什么?
评论中的一个问题的答案:
$ mount | grep "$(df ~/reference.file | awk 'NR==2{print $1}')"
/dev/sda6 on /home type ext4 (rw,noatime)
$
当然,因为是在SSD上,所以里面/etc/fstab
有
defaults,noatime
/home
在和 的行中
errors=remount-ro,noatime
在 的行中/
。
我很惊讶find
with 选项-atime -0,01
列出了最后一刻钟左右的文件和时间戳。这是 atime-information 的来源吗?它是否仅保留在 RAM 中并且重新启动后不再可用?
答案1
从 find 手册页中,查找(1):
-anewer reference
当前文件的最后一次访问时间比该文件的最后一次数据修改时间更近参考文件。
答案2
询问驱动器安装选项的评论是有道理的:我的大容量存储是 SSD,为了不因 atime 写入而过早磨损它,它安装了defaults,noatime
.但根本atime
就没有注册。人们可以像这样轻松地检查它:
a@W:~$ touch reference.file
a@W:~$ rm -f test
a@W:~$ echo $(date) > test
a@W:~$ mount | grep "$(df test | awk 'NR==2{print $1}')"
/dev/sda6 on /home type ext4 (rw,noatime)
a@W:~$ LC_ALL=C stat test # all 4 timestamps will be equal...
File: test
Size: 26 Blocks: 8 IO Block: 4096 regular file
Device: 806h/2054d Inode: 6033466 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/adalbert) Gid: ( 1002/ aoderv)
Access: 2024-02-27 09:16:54.677820647 +0100
Modify: 2024-02-27 09:16:54.677820647 +0100
Change: 2024-02-27 09:16:54.677820647 +0100
Birth: 2024-02-27 09:16:54.677820647 +0100
a@W:~$ date; cat test # reading access
2024-02-27T09:18:04+01:00
2024-02-27T09:16:54+01:00
a@W:~$ LC_ALL=C stat test
File: test
Size: 26 Blocks: 8 IO Block: 4096 regular file
Device: 806h/2054d Inode: 6033466 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/adalbert) Gid: ( 1002/ aoderv)
Access: 2024-02-27 09:16:54.677820647 +0100 # <=== NOT changed! ===
Modify: 2024-02-27 09:16:54.677820647 +0100
Change: 2024-02-27 09:16:54.677820647 +0100
Birth: 2024-02-27 09:16:54.677820647 +0100
a@W:~$ # find with -neweram reference.file will NOT see the access.
这表明读访问权限未注册。然后,即使使用正确的选项,您也根本没有机会确定使用 find 访问文件的时间。
然后我将安装选项更改/etc/fstab/
为
UUID=12345678-abcd-1234-abcd-123456789012 /home ext4 rw,nodiratime,lazytime,strictatime 0 2
这是重启后上述实验的结果:
a@W:~$ rm test
a@W:~$ echo $(date) > test
a@W:~$ mount | grep "$(df test | awk 'NR==2{print $1}')"
/dev/sda6 on /home type ext4 (rw,nodiratime,lazytime)
a@W:~$ LC_ALL=C stat test # all 4 timestamps will be equal...
File: test
Size: 26 Blocks: 8 IO Block: 4096 regular file
Device: 806h/2054d Inode: 6033466 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/adalbert) Gid: ( 1002/ aoderv)
Access: 2024-02-26 23:26:25.102982504 +0100
Modify: 2024-02-26 23:26:25.102982504 +0100
Change: 2024-02-26 23:26:25.102982504 +0100
Birth: 2024-02-26 23:26:25.102982504 +0100
a@W:~$ cat test # reading access
2024-02-26T23:26:25+01:00
a@W:~$ LC_ALL=C stat test # access time will be later than the other timestamps
File: test
Size: 26 Blocks: 8 IO Block: 4096 regular file
Device: 806h/2054d Inode: 6033466 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/adalbert) Gid: ( 1002/ aoderv)
Access: 2024-02-26 23:28:46.307180653 +0100 # <=== this is later than the other timestamps below ===
Modify: 2024-02-26 23:26:25.102982504 +0100
Change: 2024-02-26 23:26:25.102982504 +0100
Birth: 2024-02-26 23:26:25.102982504 +0100
a@W:~$ # under these circumstances, find with -neweram reference.file will see the access.
a@W:~$ # Use option -printf "%AY-%Am-%AdT%AT %p\n" to show the access time.
显示所有上次访问或修改时间戳的脚本可能如下所示:
#!/bin/bash
# ************************ 00_access.sh *************************
# List which files have been accessed since the last call of the
# script (=timestamp of ${REFERENCE}) have been read or changed
# (without files in /proc and in /sys).
#
# After a copy operation, all four times for the copy are
# are the same, including the atime. This is also the case for
# newly created files. For this reason, copied and newly created
# files are displayed here are displayed as read-only files.
# The atime of the source file during a copy operation is really
# the access access time of the copy-read operation.
#
# Call e.g:
# <path to wherer it is stored>/00_access.sh /
#
# The parameter, here /, can also be omitted. Then the
# applies from the current position in the directory tree.
#
# You can also assign this to a key (e.g. to Super-Z):
#
# bash -c "<path to wherer it is stored>/00_access.sh / >> \
# /home/$(whoami)/atime.txt; \
# if [[ -e /home/$(whoami)/refernce.file ]] ; \
# then exit ; \
# else mousepad /home/$(whoami)/atime.txt; \
# fi"
# ***************************************************************
RED="\033[1;31m"
BLUE="\033[1;34m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
MAGENTA="\033[1;35m"
NONE="\033[0m"
REFERENCE=/home/$(whoami)/reference.file # this file exists between first and second call
if [[ -e ${REFERENCE} ]]
then # ${REFERENCE} present indicates second call
notify-send "2. call of 00_access.sh"
cat ${REFERENCE}
echo "=== Read accesses or newly created (i.e. all four times the same):"
WO=$1 # variable was used during development
find ${WO} -type d \( -path /sys -o -path /proc \) \
-prune -o -name '*' \
-neweram ${REFERENCE} \
-type f \
-printf "%AY-%Am-%AdT%AT %p\n" 2>/dev/null | \
grep -v 00_access.sh | \
grep -v ${REFERENCE} | \
sort | \
ssed -R 's/^([^.]+)\.\d+ (.*)$/\1 \2/'
echo "=== modified:"
find ${WO} -type d \( -path /sys -o -path /proc \) \
-prune -o -name '*' \
-newermm ${REFERENCE} \
-type f \
-printf "%TY-%Tm-%TdT%TT %p\n" 2>/dev/null | \
grep -v 00_access.sh | \
grep -v ${REFERENCE} | \
grep -v /home/$(whoami)/atime.txt | \
sort | \
ssed -R 's/^([^.]+)\.\d+ (.*)$/\1 \2/'
echo -e "=== End: $(\date -Iseconds) 00_access.sh finished. ==="
rm ${REFERENCE} # the next call to the script will count as the first one again
notify-send "2. call to 00_access.sh finished."
echo # put an empty line below the output
else # ${REFERENCE} present indicates second call
notify-send "1. call to 00_access.sh: take note of timestamp."
# Check if atime is recorded in the calling context...
touch ${REFERENCE}
MOUNT=$(mount | grep "$(df ${REFERENCE} | awk 'NR==2{print $1}')")
if [[ ! "$(echo ${MOUNT} | grep nodiratime | grep lazytime)" ]]
then # without atime at ${REFERENCE} ?
echo -e "mounted as: ${MOUNT}\n${RED}read access can't be shown!${NONE}"
echo -e "This script will note only new created or modified files there."
fi # without atime at ${REFERENCE} ?
if [[ $1 ]]
then # was it called with a parameter?
zusätzlich prüfen, ob atime für $1 vom System mitgeschrieben wird...
MOUNT=$(mount | grep "$(df $1 | awk 'NR==2{print $1}')")
if [[ ! "$(echo ${MOUNT} | grep nodiratime | grep lazytime)" ]]
then # without atime at $1 ?
echo -e "$1 is mountet as: ${MOUNT}\n${RED}atime is not rcorded there!${NONE}"
echo -e "This script will note only new created or modified files there."
fi # without atime at $1 ?
echo -e "=== Begin: $(\date -Iseconds) 00_access.sh mit »$1« ===" > ${REFERENCE}
else # was it called with a parameter?
echo -e "=== Begin: $(\date -Iseconds) 00_access.sh ohne Argument ===" > ${REFERENCE}
fi # was it called with a parameter?
fi # ${REFERENCE} present indicates second call
第一次调用时,它仅记录开始时间reference.file
。在第二次调用时,它用于查找在offind
后被访问过的文件以及在of后被修改过的文件。输出结果后,它会删除,以便下一次调用脚本将是开始时刻。mtime
reference.file
mtime
reference.file
reference.file
有利的是,人们可以将其与键盘快捷键(例如 Super-Z)相关联,如脚本内部文档中所述。这样,它将在开始和终止调用之间累积此类文件访问注释,并在通过快捷方式进行第二次调用后在编辑器中显示它们。享受!