我一直在尝试创建一个名为 fifo 的临时文件,并在引用之后Bash:创建匿名 fifo我看到他们正在使用它mktemp -u
来获取 fifo 的文件名。手册页指出这是不安全的。
-u, --dry-run
do not create anything; merely print a name (unsafe)
为什么这不安全?我该如何负责任地使用这项技术?
答案1
上面他们所说的“不安全”的含义如下。假设你有这种情况:
- 你跑
mktemp -u
- 它会打印一个名字,比如
/tmp/tmp.njxOsokU9u
- 你将该名称保存在某处,大概是在 bash 变量中(例如
tmp
) - 您的脚本执行了一些与该文件无关的工作
- 然后你的脚本尝试使用临时文件(
echo hello > $tmp
)
没什么问题,对吧?以下是类似的场景:
- 你跑
mktemp -u
- 它会打印一个名字,比如
/tmp/tmp.njxOsokU9u
- 你将该名称保存在某处,大概是在 bash 变量中(例如
tmp
) - 您的脚本执行了一些与该文件无关的工作
- 与您的脚本无关的其他一些进程创建具有相同名称的文件(即
/tmp/tmp.njxOsokU9u
) - 然后你的脚本尝试使用临时文件(
echo hello > $tmp
)
现在您的脚本和其他进程可能会写入同一个文件,这很可能不会有好结果。这就是它被标记为不安全的原因。
答案2
在温度计,“安全”是指免受其他程序的无意干扰,尤其是由于名称冲突。mktemp 尝试向您保证,即使您的文件位于与许多其他程序共享的文件系统中,您的脚本也可能是唯一与该文件交互的脚本。mktemp 通过三种方式为您处理这个问题:
- 它使用随机字符创建名称,因此它们不太可能与其他程序(或同一脚本的其他正在运行的实例)具有相同的名称。
- 它设置文件的权限,使得只有文件的所有者才能读取和写入,从而限制可能破坏文件的其他程序的数量。
- 它检查该名称是否已被使用。换句话说,它检查该文件是否不存在。
mktemp 的试运行无法为您处理权限(#2),但是如果您愿意,可以使用 chmod 轻松地自己完成。
mktemp 文档警告您的问题是 #3。虽然在当前脚本将确保该名称未被使用然而,它不会将此信息传达给其他程序。因此,另一个程序或同时运行的同一脚本的另一个调用可能会再次调用 mktemp 并获取相同的临时文件路径。
您可能唯一想要使用它的情况mktemp --dry-run
是对于一些罕见的程序,它们不允许其输出文件或目录已经存在。在这些情况下,您可能希望通过以下方式降低名称冲突的可能性:
- 增加文件名中的随机字符的数量(上面的 mktemp 函数 #1)。
- 尽量缩短从调用 mktemp 到文件创建之间的时间间隔。同样,您可以让 mktemp 创建文件,然后在另一个命令在临时路径上创建文件之前将其删除。