如何查找重新启动之前创建/修改/访问的文件?

如何查找重新启动之前创建/修改/访问的文件?

在远程系统(我不是其管理员)上,我TMPDIR在“.profile”中配置了替代方案(因为系统默认空间非常有限)。

TMPDIR当然,这种替代方案在重新启动时不会被清除。这就是为什么我想定期(或登录时)擦除目录。但是,当我未登录时,我可能会使用长时间运行的脚本登录多次,因此实际上rm无法选择全部内容。

有没有办法(最好是在 中bash,但常用工具可用)来查找特定目录中早于最近重新启动的文件,以清理我的TMPDIR

答案1

与 Thomas 的回答相同,但使用 /proc/stat 的 btime 字段找到启动时间的更简单方法

$ DT=$(awk '$1 ~ /btime/ { print "print scalar localtime("$2")" }' /proc/stat|perl)
$ echo $DT
Fri Nov 13 15:04:28 2015
$ last reboot|head -1
reboot   system boot  3.16.0-4-amd64   Fri Nov 13 15:04 - 22:53 (5+07:49)  
$ touch -d "$DT" /tmp/foo

并使用 find 和 -newer 选项

答案2

这个简单的一行可能有助于删除TMPDIR上次重新启动之前修改的所有文件和目录:

$ find $TMPDIR -mindepth 1 -depth -not -newermt "$(uptime -s)" -delete

您的机器必须支持该功能uptime -s并具有该功能才能工作的find选项。-newerXY

-newermt是 的一种特殊形式-newerXY,在引用 (t)imestamp 之后查找 (m)odified 的文件和目录,在本例中是 的输出uptime -s

请参阅find手动的的详细信息-newerXY

使用-not我们反向-newermt 查找被修改的文件或者恰好在上次重新启动时而不是在其之后。

-depth关心在目录本身之前处理目录内容(对于递归删除很重要)。

-mindepth 1确保TMPDIR目录本身被保留。

如果你只想列表相应的文件(而不是删除它们),只需删除-delete.

如果你想列出删除只需追加-printf "%p\n" -delete

答案3

注意到该评论uptime -s是最近才出现的(出现在 Linux 特定代码中,位于2012年底)。

更便携的可能是使用 的输出last,其中列出了系统启动时间戳,例如,

tom      pts/0        michener.jexium- Wed Nov 18 17:00   still logged in
reboot   system boot  3.2.0-4-amd64    Wed Nov 18 16:47 - 20:36  (03:49)
tom      pts/0        michener.jexium- Wed Nov 18 04:12 - down   (01:21)
reboot   system boot  3.2.0-4-amd64    Wed Nov 18 04:04 - 05:33  (01:29)
tom      pts/0        michener.jexium- Tue Nov 17 17:03 - down   (04:24)

并(使用 grep 或 awk)获取最近“重新启动”行的时间戳,并使用作为 的参数touch,例如

LAST=$(last | grep -E '^reboot ' | sed -e 's/^.\{39\}//' -e 's/\(.\{16\}\).*/\1/' | head -n 1)

这会让你使用-newer以下选项find,并在一天的一小部分时间内完成重启时间:

FILE=/tmp/foo
touch -d "$LAST" $FILE
find $MY_TMPDIR ! -newer $FILE -exec echo rm -rf {} \;

当然,其弱点是了解以下格式last输出(但没有标准)。

答案4

下面是一个脚本,它解析 的输出uptime,计算自启动以来的总分钟数,并查找比几分钟前修改的文件。我在 FreeBSD 10.2、Debian Jessie 8 和 Ubuntu Trusty 14.04 上对此进行了测试。我不知道uptime其他系统上的输出格式。

其核心是函数awk中的脚本uptime_minutes,它可以单独放入命令文件中,以便在其他find命令和需要知道正常运行时间分钟数的情况下使用,可能精确到 1 分钟以内。

将其保存在文件中并执行,sh filename directory ...其中filename是您为脚本选择的名称,并且directory是您要搜索的一个或多个目录:

    #!/bin/sh

    uptime_minutes() {
        uptime |
        awk '
            {
                for (i=1; i<=NF; i++) {
                    if ($i == "up") {
                        split($(i+3), hhmm, "[:,]")
                        print ($(i+1) * 24 * 60) + (hhmm[1] * 60) + hhmm[2]
                        exit
                    }
                }
            }
        '
    }
    find "${@:?}" -mmin +$(uptime_minutes) # -exec rm {} \;

"${@:?}"如果您不提供任何目录参数,则只会打印并出现错误。

文件删除代码在末尾被注释掉。#如果您想真正删除文件而不是打印它们的名称,只需删除 即可。

相关内容