/ tmp和/ run有什么区别?


42

根据FHS-3.0/tmp适用于临时文件,/run适用于运行时变量数据。输入的数据/run必须在下次启动时删除,这对于来说不是必需的/tmp,但是程序仍然不能假定输入的数据/tmp将在下次程序启动时可用。这一切似乎和我很相似。

那么,两者有什么区别?程序应根据哪个标准来决定将临时数据放入/tmp还是放入临时数据/run

根据FHS:

程序的子目录可能为/run; 对于使用多个运行时文件的程序,建议这样做。

这表明“系统程序”和“普通程序”之间的区别不是标准,程序的生存期也不是标准(例如,长期运行与短期运行过程)。

尽管在FHS中未提供以下基本原理,/run但为了克服/var为时已晚的问题,引入了这些基本原理,需要肮脏的技巧才能/var/run尽早提供。但是,现在/run引入并在FHS中对其进行了描述,似乎没有明确的理由同时具有/run/tmp


11
/ tmp是临时数据的* nix标准位置。/ run是临时数据的Poettering标准位置。
2016年

向后兼容始终是一个原因……
Bakuriu

Answers:


16

没有理由同时拥有/ run和/ tmp

我想你是正确的。 /tmp现在我们已经基本弃用了/run。如果您的程序可以执行此操作(这要求将它作为特权操作安装),那么现在您将使用的子目录/run。这是出于安全原因。

例如,CUPS打印守护程序不是以root身份运行,而是通常从OS软件包安装。该软件包将安装/usr/lib/tmpfiles.d/cups.conf,并systemd-tmpfiles创建一个可以访问的目录。由于该目录位于下/run,因此非特权用户不能恶意声明该名称,/tmp这与世界可写的名称不同。

不能/run直接使用的“非特权程序”

真正的区别是您的程序是否由任意非特权用户使用其自己的用户ID运行。但是您通常仍然不希望使用/tmp,因为其他无特权的用户可以访问它。您更喜欢使用$XDG_RUNTIME_DIR。通常,此实现为/run/user/$(id -u)-,因此它也恰好是其的子目录/run。虽然不能保证位置。程序应始终使用环境变量。

/tmp仅对系统上不同非特权用户之间的临时合作有用。这样的临时系统容易受到恶意用户的拒绝,这些恶意用户拒绝与所有人合作并破坏事物:)。一个示例是无特权的用户决定talk使用unix套接字运行该守护程序的版本。

Lennart Poettering的原始信息

注意,下面的Poettering清单要求/tmp对“小文件”有用,而/run仅用于“通信原语”。我也不认为这种区别是正确的。的发布者/runudev,而且我很确定/run/udev包括内部数据库。一旦有了/run目录,我认为没有人希望遵循所声明的区分并创建另一个目录,以免混乱/tmp。因此,实际上,我们/run现在仅使用。

将世界可写的共享名称空间(如/ tmp)用于通信目的一直是有问题的,因为建立通信需要稳定的名称,但是稳定的名称为DoS攻击打开了大门。可以通过在早期启动期间为某些服务建立受保护的按应用程序目录来部分纠正此问题(就像我们对X11所做的那样),但这只能部分解决此问题,因为只有在每次安装软件包后都重新启动时,此方法才能正常工作。

...

Fedora的另一个功能(用于Fedora 17)通过隔离各种服务的/ tmp命名空间,更改了许多系统服务的/ tmp语义,以使其更加安全。

...

因为/ tmp不再必须是共享名称空间,所以通常不适合用作通信原语的位置。

...

确保[/ run]是tmpfs,因此在启动时会自动刷新。除此之外,不会进行任何自动清理。

...

这是一个粗略的指南,我们建议您(Linux应用程序开发人员)如何选择要使用的正确目录:

  1. 您需要一个放置套接字(或其他通信原语)的位置,并且您的代码可以特权运行:使用/ run下的子目录。(或在/ var / run下面获得额外的兼容性。)
  2. 您需要放置套接字(或其他通信原语)的位置,并且代码无特权运行:请使用$ XDG_RUNTIME_DIR下的子目录。
  3. 您需要一个地方来进行较大的下载和下载并以无特权的方式运行:使用$ XDG_DOWNLOAD_DIR。
  4. 您需要一个放置缓存文件的位置,该文​​件应该是永久的并且可以无特权地运行:请使用$ XDG_CACHE_HOME。
  5. 以上内容均不适用,您需要放置一个不需要持久性的小文件:将$ TMPDIR与/ tmp一起使用。并使用mkstemp()和mkdtemp()而不进行任何自产。
  6. 否则,将$ TMPDIR与/ var / tmp一起使用。还可以使用mkstemp()/ mkdtemp()。

请注意,以上这些规则仅由我们建议。这些规则考虑了我们对该主题的了解,并据我们所知避免了当前和将来的发行版出现问题。请考虑更新您的项目以遵循这些规则,并在编写新代码时牢记这些规则。

我们要强调的一件事是/ tmp和/ var / tmp实际上不是您的用例的正确选择。这些目录有有效的用途,但实际上通常是另一个目录可能更好。因此,请小心,考虑其他选项,但是如果您确实选择/ tmp或/ var / tmp,则至少要确保使用mkstemp()/ mkdtemp()。

/tmp如上所述,我们有点摆脱了X窗口系统使用的传统套接字。 我看错了tmpfiles.d/x11.conf。看起来更像是依靠合作:)。我认为代码已经过审核,因此拒绝服务是最糟糕的情况。


8
这个答案是各种各样的错误。
R ..

@R ..,是否愿意扩大?
2016年

是的,我已经回答了。(起初只是评论,但我意识到它更像是一个答案。)
R ..

我认为,我认为您正在努力解决的当前问题的主要缺点是,从技术上讲,需要对XDG_RUNTIME_DIR进行正确处理才能移植到任何* nix(“退回到具有类似功能的替换目录”),实际上这意味着什么 对于可移植的实用程序,最好使用定义明确的标准/tmp(“为了完全安全,使用它的唯一API应该是mkstemp(),mkdtemp()(和朋友)”)。
sourcejedi '16

答案遗漏也是常见的情况:/var/run在系统范围内(例如,与本地数据库进行通信),/tmp/现在通常是每个用户创建的。从历史上看,/ tmp的配额也设置为不同。答案错过了使用的语义区别也很重要。
Giacomo Catenazzi

23

目录/tmp/usr/tmp(后来的/var/tmp)曾经是所有人和所有人的垃圾场。这些目录中文件的唯一保护机制是粘贴位,该粘贴位将文件的删除或重命名限制为其所有者。正如marcelm在评论中指出的那样,原则上没有什么可以阻止某人使用服务使用的名称(例如nginx.pidsshd.pid)来创建文件。(实际上,启动脚本可以先删除此类伪造文件。)

/run建立用于长期服务(例如锁,套接字,pid文件等)的非持久运行时数据。由于它对于公众是不可写的,因此可以保护服务运行时数据免受混乱/tmp和清理作业的影响。确实:我运行的两个发行版(无双关)对拥有755权限/run,而/tmp/var/tmp/dev/shm就此而言)具有1777权限。


3
它只是在这里将服务运行时数据与混乱状态分离开来,/tmp而且还为遍历整个过程的各种清理作业中的数据提供了安全港/tmp
聪桂

感谢您提供有关权限的信息。但是,根据FHS,“程序可能具有/ run的子目录;对于使用多个运行时文件的程序,鼓励使用此子目录。” -这似乎与“长期服务”标准以及由于权限有限而无法创建子目录的程序都矛盾。
Dirk Herrmann

@DirkHerrmann不,不是。看看/run,并检查了所造成的复杂的(嗯...)的目录结构udevudisk等等。我不是这个特殊问题的专家,但我猜的启动脚本(这是运行作为超级用户)设置好一切。

2
“ / run从技术上讲不是必需的,只是在那里将服务运行时数据与/ tmp中的混乱分开。” -也是一件好事,因此没有特权的进程不能蹲下系统服务要使用的名称。如果nginx想要使用,Kinda很烂,/tmp/nginx.pid但是由于某些行为不正常的程序,它已经存在。/run/通过要求写入特权来防止这种情况。
marcelm

18

/tmp是用于创建临时文件和目录的位置。它不能用于存储“知名名称”(即,无需您以某种方式将名称传达给另一个进程就可以知道的名称),因为没有人拥有名称空间的所有权;任何人都可以在那里创建文件。因此,通常在拥有需要文件(即不是管道等)作为输入或输出的实用程序时使用它,只要您传入名称,任何(随机生成的)名称都可以使用。

从历史上看,某些事物(例如X)违反了该原理,并在中添加了众所周知的名称(例如.X11-unix/tmp。这当然是有问题的,并且允许任何用户通过首先争先使用所需名称创建文件来对需要的服务进行DoS。这些东西属于/run(或者/var/run如果您不订阅Freedesktop.org修订主义,则属于)。当然,更好的办法是修复它们,使其不使用全局名称空间中的知名名称,而绕过路径名。


感谢您对“临时文件”的更多定义。尽管我不认为“绕过路径名”解释了如何建立协调点。即通常您将使用环境变量。看起来没有足够的套接字和管道(通常使用)可以正常工作。(部分原因是很多事情将在同一dbus套接字上运行)。如果程序默认为硬编码路径,则设置环境似乎很烦人。您可以向systemd .socket文件添加新密钥...但这对整个目录或新安装的服务均
无济于事

2
/run/本身被FHS采用,我看不出它与fd.o有什么关系。除非我们真正要抱怨的是没有做出具体贡献的发展努力,否则两者都会做出贡献。
sourcejedi '16

我确实认为这里的最初答案是这里所写问题的最佳答案。我认为可以通过考虑以下方法来进一步改进:_当软件具有对专用目录(例如下的)的写访问权限时/run,它可能选择避免使共享/tmp目录中的文件过多。
sourcejedi

什么是“ fd.o”?
TRiG

7

根据文件系统层次结构标准,

  • /run 用于运行时变量数据,即自重新启动以来有关正在运行的系统的信息
  • /tmp 是临时文件的通用位置。

因此,有关守护程序状态,已登录用户,已安装的可移动设备等的所有内容都将进入,/run而程序创建的临时文件将进入/tmp

编辑:正如@JdeBP在下面的评论中指出的那样,

FHS允许执行诸如cron作业的常规设置之类的工作,这些工作会定期清除/tmp“旧”文件;没有这样的机制/run。因此严格限制了程序对放入的任何东西的寿命的期望/tmp。尽管程序可以期望文件在/run连续运行的系统中生存的时间更长,但它们也可以在更多的情况下进行整理。


4
在此答案或任何其他答案中并未指出但在FHS中指出的一件事,您可能希望通过以下方法来改善答案:FHS允许执行诸如cron作业的常规设置之类的事情,这些活动会定期清除/tmp“旧”文件;没有这样的机制/run。因此严格限制了程序预期放入的任何东西的寿命/tmp。尽管程序可以期望文件在/run连续运行的系统中生存更长的时间,但它们也有望在更多的情况下进行整理。
JdeBP

1
最好在进程死后立即将每个进程的目录都消失(或允许某些漫游垃圾守护程序删除)。
1998年

1
@Omnifarious现在可以通过使用RuntimeDirectory = :-) 获得针对systemd服务的该行为。
sourcejedi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.