在bash中创建临时文件

Str*_*sky 140 unix linux bash

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

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

koj*_*iro 171

mktemp(1)手册页解释了它相当好:

传统上,许多shell脚本使用pid作为后缀的程序名称,并将其用作临时文件名.这种命名方案是可预测的,它创建的竞争条件很容易让攻击者获胜.更安全但更低级的方法是使用相同的命名方案创建临时目录.虽然这确实可以保证不会破坏临时文件,但它仍然允许简单的拒绝服务攻击.由于这些原因,建议使用mktemp代替.

在脚本中,我调用类似的mktemp

mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")
Run Code Online (Sandbox Code Playgroud)

这创建了一个我可以工作的临时目录,并且我可以安全地将实际文件命名为可读和有用的东西.

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


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

  • 也可以在脚本执行结束时删除tempdir:`trap"rm -rf $ mydir"EXIT` (11认同)
  • 似乎使用`mktemp`最安全和最跨平台的方式是与`basename`结合使用,就像`mktemp -dt"$(basename $ 0).XXXXXXXXXX"`.如果在没有`basename`的情况下使用,你可能会收到类似这样的错误_mktemp:无效模板,`/ tmp/MOB-SAN-JOB1-183-ScriptBuildTask-7300464891856663368.sh.XXXXXXXXX',包含目录separator_. (7认同)
  • 忽略他们错字(额外的空间).`mktemp -dt"$(basename $ 0).XXXXXXXXXX"`是正确的方法. (7认同)
  • @ i4niac:你需要**引用`$ 0`,在OS X的土地上有足够的空间.`mktemp -dt"$(basename"$ 0").XXXXXX"` (3认同)
  • -t 选项已弃用:http://www.gnu.org/software/coreutils/manual/html_node/mktemp-invocable.html (2认同)

Pau*_*aul 38

是的,使用mktemp.

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

> mktemp
/tmp/tmp.xx4mM3ePQY
>
Run Code Online (Sandbox Code Playgroud)


Joh*_*nce 17

你可能想看一下 mktemp

mktemp实用程序获取给定的文件名模板并覆盖其中的一部分以创建唯一的文件名.模板可以是附加了一些"X"的任何文件名,例如/tmp/tfile.XXXXXXXXXX.尾随的'Xs'被当前进程号和随机字母的组合替换.

更多细节:man mktemp


ken*_*orb 11

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

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


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

TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR"
Run Code Online (Sandbox Code Playgroud)

或临时文件:

TMPFILE=".${0##*/}-$$" && touch "$TMPFILE"
Run Code Online (Sandbox Code Playgroud)

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

按照man mktemp,我们可以阅读:

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

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

  • 不完全是什么问题.然而,它可以是一个完美的解决方案. (2认同)
  • 确实确实改善了答案。不过,我的赞成票已经是您的了。不能再投票了。我的一个建议是解释`$ {0 ## * /}`和`$$`扩展到什么,或链接到有关它的一些文档。 (2认同)

Bar*_*nes 9

mktemp可能是最通用的,特别是如果您计划使用该文件一段时间。

如果您只需要暂时将该文件作为另一个命令的输入,您还可以使用进程替换运算符,例如: <()

$ diff <(echo hello world) <(echo foo bar)
Run Code Online (Sandbox Code Playgroud)