有客观的更好的方法在bash脚本中创建临时文件吗?
我通常只要给他们起名就可以使用它们,例如tempfile-123,因为脚本结束后它将被删除。除了覆盖当前文件夹中可能的tempfile-123之外,这样做是否有其他缺点?还是以更谨慎的方式创建临时文件有什么好处?
tempfile(1)
在具有此功能的系统上使用。
有客观的更好的方法在bash脚本中创建临时文件吗?
我通常只要给他们起名就可以使用它们,例如tempfile-123,因为脚本结束后它将被删除。除了覆盖当前文件夹中可能的tempfile-123之外,这样做是否有其他缺点?还是以更谨慎的方式创建临时文件有什么好处?
tempfile(1)
在具有此功能的系统上使用。
Answers:
该mktemp(1)
手册页解释了它相当好:
传统上,许多shell脚本使用pid作为后缀来命名程序名称,并将其用作临时文件名。这种命名方案是可预测的,并且它创造的竞争条件很容易使攻击者获胜。一种更安全(尽管仍然较差)的方法是使用相同的命名方案创建一个临时目录。尽管这样做确实可以保证不会破坏临时文件,但它仍然允许进行简单的拒绝服务攻击。由于这些原因,建议使用mktemp代替。
在脚本中,我调用mktemp之类的
mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")
这会创建一个我可以使用的临时目录,并可以在其中安全地命名实际文件,使之可读且有用。
mktemp
虽然不是标准的,但是它确实存在于许多平台上。“ X”通常会转换为某种随机性,更多的可能更随机。但是,某些系统(例如busybox灰)对该随机性的限制比其他系统更大
顺便说一句,临时文件的安全创建不仅对shell脚本而言重要。这就是为什么python具有tempfile,perl具有File :: Temp,ruby具有Tempfile等的原因。
mktemp
与组合basename
,像这样mktemp -dt "$(basename $0). XXXXXXXXXX"
。如果不使用,basename
可能会收到类似mktemp的错误:无效的模板,`/ tmp / MOB-SAN-JOB1-183-ScriptBuildTask-7300464891856663368.sh.XXXXXXXXXX',包含目录分隔符。
mktemp -dt "$(basename $0).XXXXXXXXXX"
是正确的方法。
$0
,有位在OS X的土地有的是mktemp -dt "$(basename "$0").XXXXXX"
trap "rm -rf $mydir" EXIT
您可能想看看 mktemp
mktemp实用程序采用给定的文件名模板,并覆盖其中的一部分以创建唯一的文件名。该模板可以是任何文件名,并附加了一些“ X”,例如/tmp/tfile.XXXXXXXXXX。尾随的“ X”将替换为当前进程号和随机字母的组合。
有关更多详细信息:man mktemp
以更谨慎的方式创建临时文件有什么好处
临时文件通常/tmp
在所有其他用户和进程具有读写访问权限的临时目录(例如中)中创建(任何其他脚本都可以在其中创建新文件)。因此,脚本在创建文件时应格外小心,例如使用具有正确权限的文件(例如,对所有者只读,请参阅:),help umask
并且文件名不应轻易猜到(理想情况下是随机的)。否则,如果文件名不是唯一的,则可能与多次运行相同的脚本产生冲突(例如,竞争条件),或者某些攻击者可能劫持一些敏感信息(例如,当权限太开放且文件名容易猜测时),或者使用自己的代码版本创建/替换文件(例如根据所用内容替换命令或SQL查询)已存储)。
您可以使用以下方法来创建临时目录:
TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR"
或临时文件:
TMPFILE=".${0##*/}-$$" && touch "$TMPFILE"
但是,它仍然是可预见的,并不被认为是安全的。
按照man mktemp
,我们可以阅读:
传统上,许多shell脚本使用pid作为后缀来命名程序名称,并将其用作临时文件名。这种命名方案是可预测的,并且它创建的竞赛条件很容易使攻击者获胜。
为安全起见,建议使用mktemp
命令创建唯一的临时文件或目录(-d
)。
${0##*/}
并$$
扩展或链接到有关它的一些文档。