他のファイルが作成または変更された後にアクセスされたすべてのファイルを検索する-newerXYオプションは何ですか?

他のファイルが作成または変更された後にアクセスされたすべてのファイルを検索する-newerXYオプションは何ですか?

重要な場合、この問題は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その後、上記のコマンドがあります。並列プロセスの他のファイルのうち、2番目のコマンド/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。 2番目の呼び出しでは、findof以降にアクセスされたファイルとそれ以降に変更されたファイルを見つけるために使用されます。結果の出力後、次のスクリプト呼び出しは開始時刻になるように削除されます。mtimereference.filemtimereference.filereference.file

スクリプトの内部ドキュメントで説明されているように、Super-Zなどのキーボードショートカットに関連付けることができるという利点があります。これにより、呼び出しの開始と終了の間にファイルアクセスコメントが蓄積され、ショートカットを介して2回目の呼び出し後にエディタに表示されます。楽しむ!

関連情報