我正在将 Asterisk 通话录音从我们的主服务器复制到 samba 共享,并且创建日期和时间已更改为当前日期和时间。
文件格式为:in-xxxxxxxxxx-xxxxxxxxxx-20211020-162749-1634761669.7921917.wav
粗体部分为EPOCH时间。我有数百个这样的文件,我需要根据文件名中的 EPOCH 时间戳更改文件的创建日期。谁能帮我?
Sté*_*las 11
使用 GNU touch
,您可以将文件的最后修改时间touch -d @1634761669.7921917 file
设置为指定的纪元时间(即使使用亚秒精度,如下所示)。
所以你可以这样做zsh
:
#! /bin/zsh -\nret=0\nfor file in *-<->.<->.wav; do\n t=${file:r} t=${t##*-}\n touch -d @$t -- $file || ret=$?\ndone\nexit $ret\n
Run Code Online (Sandbox Code Playgroud)\n如果确实是创建时间(通常称为出生时间)ls -l --time=birth
,例如您想要更改的GNU 最新版本的报告ls
,那么在 Linux 上除了将时钟更改回该时间并创建再次归档。
下面的部分是错误的,它并没有像我最初认为的那样改变名称空间中的时间。有关详细信息,请参阅@Busindre 的答案。
\n例如,与:
\nsudo unshare --time sh -c \'date -s @1634761669.7921917 && exec cp -a file file.new\'\n
Run Code Online (Sandbox Code Playgroud)\n您将创建一个出生时间接近的file.new
副本file
@1634761669.7921917
$ sudo unshare --time sh -c \'date -s @1634761669.7921917 && exec cp -a file file.new\'\n$ ls -l --time=birth --time-style=+%s.%N file file.new\n-rw-r--r-- 1 stephane stephane 0 1642699170.474916807 file\n-rw-r--r-- 1 stephane stephane 0 1634761669.792191700 file.new\n
Run Code Online (Sandbox Code Playgroud)\n上面的脚本zsh
可以写成:
#! /bin/zsh -\nret=0\nfor file in *-<->.<->.wav; do\n t=${file:r} t=${t##*-}\n \n unshare --time sh -c \'\n date -s "@$1" && exec cp -aTn -- "$2" "$2.new"\' sh "$t" "$file" &&\n mv -f -- "$file.new" "$file" || ret=$?\ndone\nexit $ret\n
Run Code Online (Sandbox Code Playgroud)\n(并且需要作为 运行root
)。
我刚刚意识到这会导致一个潜在的问题:unshare --time
黑客允许将出生时间设置为过去的某个任意时间,但这也会导致更改状态时间(例如报告的时间ls -lc
)设置为过去的时间,即指定的时间,加上制作副本所需的时间)。
ctime也不意味着可以任意设置。通过像这样将其设置为过去,它可能会打破某些软件可能对这些文件所做的假设。例如,备份软件可能决定忽略它,因为它的 ctime 早于上次备份时间。
\n因此,最好确保 ctime 未在该名称空间中设置为伪造的时钟时间,例如,仅在过去创建文件,但在当前复制其内容:
\nunshare --time sh -Cc \'\n umask 77 && date -s "@$1" && : > "$2.new"\' sh "$t" "$file" &&\n cp -aT -- "$file" "$file.new" &&\n mv -f -- "$file.new" "$file"\n
Run Code Online (Sandbox Code Playgroud)\n\xc2\xb9 您需要 Linux 内核 5.6 或更高版本,并CONFIG_TIME_NS
在内核 2.36 或更高版本中启用util-linux
。