/tmp目录是如何清理的?

/tmp目录是如何清理的?是自动的吗?如果是的话,清理频率是多少?

19我的临时文件从不写入磁盘,而是写入RAM磁盘。我在/etc/fstab中添加了tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0 - Anonymous
相关链接:https://serverfault.com/questions/377348/when-does-tmp-get-cleared/377349 - Ciro Santilli OurBigBook.com
请参考Serverfault:什么时候会清空/tmp目录? - Avatar
8个回答

注意!此答案自至少ubuntu 14.04以来已过时。请查看其他答案以了解当前情况,如果它们被证明正确,请疯狂点赞。同时,请发表评论,以便我可以在此处放置当前正确答案的链接。
对于14.04,请参阅https://askubuntu.com/a/759048/1366 对于16.10,请参阅https://askubuntu.com/a/857154/453746

2011年的旧答案:

/tmp目录的清理是由upstart脚本/etc/init/mounted-tmp.conf完成的。该脚本在每次挂载/tmp时由upstart运行。实际上,这意味着每次启动都会运行该脚本。

该脚本大致执行以下操作:如果/tmp中的文件比$TMPTIME天要旧,那么它将被删除。

$TMPTIME的默认值为0,这意味着/tmp中的每个文件和目录都会被删除。 $TMPTIME是在/etc/default/rcS中定义的环境变量。


1这对于14.04版本来说不再是真实的(这个脚本已经不存在了)。 - Martin Schröder
@Martin Schröder - 这个脚本存在于我的系统上,而且是一个干净的14.04安装,tmpreaper不存在! - Lance Holland
我现在正在使用Arch Linux,所以无法验证。抱歉。请有人来验证并评论或编辑我的答案。 - Lesmana
4在Ubuntu 16.04中,tmpreaper已被放弃使用,因为不安全。请查看:https://fossies.org/linux/tmpreaper/debian/README.security - tamerlaha
1不。在Ubuntu 16.04中,它只是被systemd机制取代了。阅读那份文件,你实际上会发现一个解释,说明声称存在安全问题的安全分析是有缺陷的。 - JdeBP

默认情况下,每次启动时目录都会被清空,因为TMPTIME默认为0。
您可以在以下文件中更改时间。
/etc/default/rcS

TMPTIME 表示临时文件夹应该以天为单位清理的频率


13每次启动时清除是对于从不重启的机器(如服务器)来说并不理想。因为我的服务器已经运行了378天,我的/tmp 目录里有超过500,000个文件占用了5Gb的空间。我不太愿意重启它,因为在重启时清除这些文件可能需要几个小时。 - rjmunro
11在你的情况下,你应该给tmpreaper一个机会。 - qbi
1一个 Cron 作业可以轻松解决这个问题。 - Ken Sharp
另外,tmpwatch 应该是一个合适的工具。 - ArekBulski
我在这个问题上和@KenSharp持相同的观点:对于一个运行时间如此长的服务器,使用CRON作业是一个好办法。请参考http://askubuntu.com/questions/2368/how-do-i-set-up-a-cron-job。 - Yuri Sucupira
1看起来Ubuntu/systemd已经提供了一个解决方案。我想多说点什么,但是......systemd。 - Ken Sharp
3cat: /etc/default/rcS: No such file or directory - user677955
@rjmunro另一方面,你不能在目录仍在运行时仅仅擦除它。我们能确定哪个进程(PID和命令)创建了该文件,并且它是否仍然存在吗?这将有助于解决问题。 - timuçin
1@timuçin 我的评论是8年前的,但是没错,你不能在运行时直接清空 /tmp - 会导致一些问题。主要我只是想说,在重启时删除 /tmp 不一定是一个好策略。通常更好的方法是设置一个cron任务,定期删除一段时间之前的文件。 - rjmunro
@rjmunro 我并不是在质疑你的观点,只是在推测它如何被实施。 - timuçin

虽然/tmp文件夹不适合长期存储文件,但有时您可能想要将文件保留更长一些时间,而不是在下次重新启动时被清除,这是Ubuntu系统的默认设置。我知道在测试过程中,有时候我会将一些东西下载到/tmp文件夹中,然后在进行更改后重新启动,结果原始数据就丢失了。如果您希望保留/tmp文件夹中的文件时间更长一些,您可以进行一些更改。
修改/tmp清理频率
系统默认设置会在重新启动时清除/tmp文件夹中的内容,这个设置保存在/etc/default/rcS文件中。我们要关注的值是TMPTIME。
当前的TMPTIME=0表示无论文件的年龄如何,在重新启动时都会删除文件。如果将此值更改为其他正数,将会改变文件在/tmp文件夹中存活的天数。
TMPTIME=7

这个设置将允许文件在/tmp目录中保留一周,然后在下次重启时删除它们。一个负数(TMPTIME=-1)告诉系统永远不要删除/tmp目录中的任何文件。这可能不是你想要的,但是可供选择。

1好的解释。但是清理命令在哪个脚本中?我看到了/etc/init/mounted-temp.conf,但它有一行start on mounted MOUNTPOINT=/tmp让我觉得它不适用。 - enzotib
8如果你不想让文件自动删除,在/tmp目录中放置文件时,可以将其放在/var/tmp目录中。 - Gilles 'SO- stop being evil'
1当你的机器崩溃时,保留那些你不想丢失的文件(渲染视频帧)也是很方便的,可能是由于内存不足引起的。当然,更好的解决办法是修复这个问题。 :-) - Ken Sharp
可以在Cygwin里面完成吗? - CMCDragonkai
我认为最好将这些较长期的临时文件保存在/var/tmp目录下(正如Gilles所说)。然后你可以像Arch Linux一样将/tmp挂载为tmpfs。 - Guildenstern

我正在Ubuntu 16.10上进行检查。我可以证实,编辑/etc/default/rcS不再起作用,无论您在该文件中放入什么内容,重启后tmp文件夹都会被清空。正如其他人提到的,tmpreaper不再使用。
我认为正确的答案是Ubuntu 16.10有一个新的设置。在/etc/tmpfiles.d文件夹中,有一个在"tmpfiles.d"手册中有记录的配置文件,用于控制是否清除/tmp文件夹。这就是我所做的,以防止重启时清除/tmp文件夹中未满20天的文件。
#/etc/tmpfiles.d/tmp.conf

d /tmp 1777 root root 20d

如果您不希望文件被删除,请将"20d"替换为"-"。这是我最好的努力,那个页面的细节几乎是晦涩难懂的。
新设置的优点是即使系统没有重新启动(例如始终开启的服务器),文件清理程序仍然可以运行。我认为这是一个重大的优势。

11man tmpfiles.d - Martin Schröder
1我发现你可以通过使用连字符来保留原始文件的权限和所有者:d /tmp/ - - - 20d - Dave Yarwood
5值得注意的是:你可以通过手动运行清理任务来测试你的配置:systemctl start systemd-tmpfiles-clean - Dave Yarwood
@pauljohn32 这对16.10之后的版本也适用吗? - kapad
3@kapad:我刚刚验证了一下,在Ubuntu 18.04上也可以运行。 - Gene Vincent
5创建 /etc/tmpfiles.d/tmp.conf 会覆盖 /usr/lib/tmpfiles.d/tmp.conf,导致其他目录的配置丢失,除非进行复制(例如 /var/tmp/systemd-private-%b-*)。请参考源代码 - Mihai Capotă
新的链接到Ubuntu的配置文件:https://git.launchpad.net/ubuntu/+source/systemd/tree/tmpfiles.d/tmp.conf?h=ubuntu%2Ffocal 它包含了q /tmp 1777 root root 10dq /var/tmp 1777 root root 30d - mgutt

在Ubuntu 14.04中,这是通过tmpreaper来完成的,它由cron每天调用(从/etc/cron.daily)。该程序可以通过/etc/default/rcS/etc/tmpreaper.conf进行配置。

在我的系统上,/etc/cron.daily 中没有 tmpreaper -- 但是我可以使用 apt-get 安装它。 - Joe Germuska
2注意:不应在16和18上安装tmpreaper,因为它已经内置了一个系统。 - jitbit

在一个使用systemd的Ubuntu(15.10及更高版本)中,这是通过systemd来完成的,使用systemd-tmpfiles-clean服务和定时器:
$ systemctl cat systemd-tmpfiles-clean.service 
# /lib/systemd/system/systemd-tmpfiles-clean.service
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Cleanup of Temporary Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=local-fs.target time-sync.target
Before=shutdown.target

[Service]
Type=oneshot
ExecStart=/bin/systemd-tmpfiles --clean
IOSchedulingClass=idle

$ systemctl cat systemd-tmpfiles-clean.timer  
# /lib/systemd/system/systemd-tmpfiles-clean.timer
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Daily Cleanup of Temporary Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)

[Timer]
OnBootSec=15min
OnUnitActiveSec=1d

您可以使用systemctl edit systemd-tmpfiles-clean.timer更改计时器行为,还可以使用各种systemd Timer 配置选项(请参见man 5 systemd.timer)。
因此,systemd-tmpfiles-clean在关机时运行,并且在其他时间每天运行一次。它清理的文件可以使用/etc/tmpfiles.d进行扩展(在另一个答案中提到)。
有趣的是,默认情况下/etc/tmpfiles.d为空。定义/tmp策略的文件在这里:
/usr/lib/tmpfiles.d/tmp.conf

实际内容:
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

# See tmpfiles.d(5) for details

# Clear tmp directories separately, to make them easier to override
D /tmp 1777 root root -
#q /var/tmp 1777 root root 30d

所以,正如已经提到的那样,要覆盖它,您可以参考关于tmpfiles.d的其他答案


我把定时器改成了20分钟,而且状态命令显示它实际上正在使用20分钟的配置。但我的问题是/tmp仍然没有清理掉。我需要它被清理掉。即使手动启动sudo systemctl start systemd-tmpfiles-clean也没有起作用。有什么想法为什么会这样? - user2932688
@ValerioBozz,请查看我提供的答案链接:https://askubuntu.com/a/857154/158442 - muru
我正在删除我的评论,因为现在已经整合了。 - Valerio Bozz

14.04之前:

每次重启后都会被清理。


从14.04版本开始,它只使用tmpreaper,而不是“每次启动”脚本。 - rogerdpack
我的14.04系统在重新启动时都会清理干净。甚至从未听说过tmpreaper - Ken Sharp
如果您从未重新启动系统会怎样? - phuclv

在我们运行Ubuntu的一台服务器上,有一个脚本用于每晚清理/tmp目录中的文件。
脚本内容如下:
#!/bin/sh
# Clean file and dirs more than 3 days old in /tmp nightly

/usr/bin/find /tmp -type f -atime +2 -mtime +2  |xargs  /bin/rm -f &&

/usr/bin/find /tmp -type d -mtime +2 -exec /bin/rm -rf '{}' \; &&

/usr/bin/find /tmp -type l -ctime +2 |xargs /bin/rm -f &&

/usr/bin/find -L /tmp -mtime +2 -print -exec rm -f {} \;

只需将上述内容保存到一个文件中,对该文件进行chmod 775操作,并创建一个cron条目来运行它。由于这是一个Web服务器,出于明显的原因,我们不希望重新启动它。


7你最好使用tmpwatch - poolie
13最后一行非常危险。通常,每个人都可以运行ln -s /usr /tmp/kaboom甚至ln -s /* /tmp/... - Daniel Alder