중요한 경우 이 문제는 Xubuntu 22.04와 관련이 있습니다. 그러나 이는 일반적인 Unix 문제일 수 있습니다.
쉘 스크립트에서 먼저 다음과 같은 참조 파일을 만듭니다.
echo $(date) > ~/reference.file
그런 다음 작업 흐름의 특정 단계까지 일부 응용 프로그램을 시작하고 싶습니다. 나는 알고 싶다,지금까지 애플리케이션이 어떤 파일에 액세스했습니까?.
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
지난 15분 동안의 파일과 타임스탬프를 나열한다는 사실에 놀랐습니다 . 이것이 시간 정보의 출처입니까? RAM에만 남아 있고 재부팅 후에는 더 이상 사용할 수 없나요?
답변1
찾기 매뉴얼 페이지에서,찾기(1):
-anewer reference
현재 파일은 파일의 마지막 데이터 수정 시간보다 최근에 마지막으로 액세스되었습니다.인용하다문서.
답변2
드라이브 장착 옵션에 대해 묻는 설명은 의미가 있습니다. 내 대용량 저장소는 SSD이고 atime 쓰기로 인해 조기에 마모되지 않도록 하기 위해 mount 입니다 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
. 두 번째 호출에서는 find
of 이후에 액세스된 파일과 이후에 수정된 파일을 찾는 데 사용됩니다 . 결과 출력 후에는 다음 스크립트 호출이 시작 시간이 되도록 삭제됩니다.mtime
reference.file
mtime
reference.file
reference.file
스크립트의 내부 문서에 설명된 대로 Super-Z와 같은 키보드 단축키와 연결할 수 있다는 이점이 있습니다. 이렇게 하면 호출 시작과 종료 사이에 파일 액세스 주석이 누적되고 바로가기를 통해 두 번째 호출 후에 편집기에 표시됩니다. 즐기다!