在bash中创建临时文件

时间:2012-06-11 15:15:06

标签: linux bash unix

是否有客观上更好的方法在bash脚本中创建临时文件?

我通常只是将它们命名为我想到的任何内容,例如tempfile-123,因为它将在脚本结束时被删除。除了覆盖当前文件夹中可能的tempfile-123之外,还有什么不利吗?或者以更仔细的方式创建临时文件有什么好处?

5 个答案:

答案 0 :(得分:164)

mktemp(1)手册页解释得相当不错:

  

传统上,许多shell脚本都使用程序的名称   pid作为后缀并将其用作临时文件名。这种类型的   命名方案是可预测的,它创造的竞争条件是   攻击者很容易获胜。一种更安全但更低劣的方法   是使用相同的命名方案创建一个临时目录。而   这确实可以保证临时文件不会   颠覆了,它仍然允许简单的拒绝服务攻击。对于   这些原因建议改为使用mktemp。

在脚本中,我调用类似

的mktemp
mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")

创建了一个我可以使用的临时目录,并且我可以安全地将实际文件命名为可读和有用的文件。

mktemp不是标准的,但它确实存在于许多平台上。 “X”通常会转换成一些随机性,更多可能会更随机;但是,有些系统(busybox ash,一个)比其他系统更加明显地限制了这种随机性


顺便说一下,安全创建临时文件不仅仅是shell脚本。这就是为什么python有tempfile,perl有File::Temp,ruby有Tempfile等等......

答案 1 :(得分:36)

是的,请使用mktemp

它将在用于存储临时文件的文件夹中创建一个临时文件,它将保证您具有唯一的名称。它输出该文件的名称:

> mktemp
/tmp/tmp.xx4mM3ePQY
>

答案 2 :(得分:17)

您可能需要查看mktemp

  

mktemp实用程序获取给定的文件名模板并覆盖a          它的一部分来创建一个唯一的文件名。模板可以是任何模板          例如,带有一些“X”的文件名          /tmp/tfile.XXXXXXXXXX。尾随的'Xs'被替换为当前进程号和随机字母的组合。

有关详情:man mktemp

答案 3 :(得分:11)

  

以更谨慎的方式创建临时文件是否有任何优势

临时文件通常在临时目录(例如/tmp)中创建,其中所有其他用户和进程都具有读写访问权限(任何其他脚本都可以在那里创建新文件)。因此,脚本应该小心创建文件,例如使用正确的权限(例如,只读给所有者,请参阅:help umask),文件名应该不容易猜到(理想情况下是随机的)。否则,如果文件名不是唯一的,它可能会与多次运行的相同脚本(例如race condition)产生冲突,或者某些攻击者可能会劫持某些敏感信息(例如,当权限过于开放且文件名很容易时猜测)或用他们自己的代码版本创建/替换文件(比如根据存储的内容替换命令或SQL查询)。

您可以使用以下方法创建临时目录:

TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR"

或临时文件:

TMPFILE=".${0##*/}-$$" && touch "$TMPFILE"

然而,它仍然是可预测的,并且不被认为是安全的。

根据man mktemp,我们可以阅读:

  

传统上,许多shell脚本使用pid作为后缀的程序名称,并将其用作临时文件名。这种命名方案是可预测的,它创建的竞争条件很容易让攻击者获胜。

为安全起见,建议使用mktemp命令创建唯一的临时文件或目录(-d)。

答案 4 :(得分:1)

mktemp可能是用途最广的,尤其是当您计划使用该文件一段时间时。

如果您仅临时需要文件作为其他命令的输入,则也可以使用进程替换运算符 <(),例如:

$ diff <(echo hello world) <(echo foo bar)