专栏首页阮一峰的网络日志Bash 脚本如何创建临时文件:mktemp 命令和 trap 命令教程

Bash 脚本如何创建临时文件:mktemp 命令和 trap 命令教程

有时,Bash 脚本需要创建临时文件或临时目录。

常见的做法是,自己在/tmp目录里面生成一个文件,这样做有很多弊端。本文介绍如何安全地处理临时文件。

一、临时文件的安全问题

直接创建临时文件,尤其在/tmp目录里面,往往会导致安全问题。

首先,/tmp目录是所有人可读写的,任何用户都可以往该目录里面写文件。创建的临时文件也是所有人可读的。

$ touch /tmp/info.txt
$ ls -l /tmp/info.txt
-rw-r--r-- 1 ruanyf ruanyf 0 12月 28 17:12 /tmp/info.txt

上面命令在/tmp目录直接创建文件,该文件默认是所有人可读的。

其次,如果攻击者知道临时文件的文件名,他可以创建符号链接,链接到临时文件,可能导致系统运行异常。攻击者也可能向脚本提供一些恶意数据。因此,临时文件最好使用不可预测、每次都不一样的文件名。

最后,临时文件使用完毕,应该删除。但是,脚本意外退出时,往往会忽略清理临时文件。

二、临时文件的最佳实践

脚本生成临时文件,应该遵循下面的规则。

  • 创建前检查文件是否已经存在。
  • 确保临时文件已成功创建。
  • 临时文件必须有权限的限制。
  • 临时文件要使用不可预测的文件名。
  • 脚本退出时,要删除临时文件(使用trap命令)。

三、mktemp 命令的用法

mktemp命令就是为安全创建临时文件而设计的。虽然在创建临时文件之前,它不会检查临时文件是否存在,但是它支持唯一文件名和清除机制,因此可以减轻安全攻击的风险。

直接运行mktemp命令,就能生成一个临时文件。

$ mktemp
/tmp/tmp.4GcsWSG4vj

$ ls -l /tmp/tmp.4GcsWSG4vj
-rw------- 1 ruanyf ruanyf 0 12月 28 12:49 /tmp/tmp.4GcsWSG4vj

上面命令中,mktemp命令生成的临时文件名是随机的,而且权限是只有用户本人可读写。

Bash 脚本使用mktemp命令的用法如下。

#!/bin/bash

TMPFILE=$(mktemp)
echo "Our temp file is $TMPFILE"

为了确保临时文件创建成功,mktemp命令后面最好使用 OR 运算符(||),指定创建失败时退出脚本。

#!/bin/bash

TMPFILE=$(mktemp) || exit 1
echo "Our temp file is $TMPFILE"

为了保证脚本退出时临时文件被删除,可以使用trap命令指定退出时的清除操作(详见后文)。

#!/bin/bash

trap 'rm -f "$TMPFILE"' EXIT

TMPFILE=$(mktemp) || exit 1
echo "Our temp file is $TMPFILE"

四、mktemp 命令的参数

-d参数可以创建一个临时目录。

$ mktemp -d
/tmp/tmp.Wcau5UjmN6

-p参数可以指定临时文件所在的目录。默认是使用$TMPDIR环境变量指定的目录,如果这个变量没设置,那么使用/tmp目录。

$ mktemp -p /home/ruanyf/
/home/ruanyf/tmp.FOKEtvs2H3

-t参数可以指定临时文件的文件名模板,模板的末尾必须至少包含三个连续的X字符,表示随机字符,建议至少使用六个X。默认的文件名模板是tmp.后接十个随机字符。

$ mktemp -t mytemp.XXXXXXX
/tmp/mytemp.yZ1HgZV

五、trap 命令的用法

trap命令用来在 Bash 脚本中响应系统信号。

最常见的系统信号就是 SIGINT(中断),即按 Ctrl + C 所产生的信号。trap命令的-l参数,可以列出所有的系统信号。

$ trap -l
 1) SIGHUP   2) SIGINT   3) SIGQUIT
 4) SIGILL   5) SIGTRAP  6) SIGABRT
 ... ...

trap的命令格式如下。

$ trap [动作] [信号]

上面代码中,"动作"是一个 Bash 命令,"信号"常用的有以下几个。

  • HUP:编号1,脚本与所在的终端脱离联系。
  • INT:编号2,用户按下 Ctrl + C,意图让脚本中止运行。
  • QUIT:编号3,用户按下 Ctrl + 斜杠,意图退出脚本。
  • KILL:编号9,该信号用于杀死进程。
  • TERM:编号15,这是kill命令发出的默认信号。
  • EXIT:编号0,这不是系统信号,而是 Bash 脚本特有的信号,不管什么情况,只要退出脚本就会产生。

trap命令响应EXIT信号的写法如下。

$ trap 'rm -f "$TMPFILE"' EXIT

上面命令中,脚本遇到EXIT信号时,就会执行rm -f "$TMPFILE"

trap 命令的常见使用场景,就是在 Bash 脚本中指定退出时执行的清理命令。

#!/bin/bash

trap 'rm -f "$TMPFILE"' EXIT

TMPFILE=$(mktemp) || exit 1
ls /etc > $TMPFILE
if grep -qi "kernel" $TMPFILE; then
  echo 'find'
fi

上面代码中,不管是脚本正常执行结束,还是用户按 Ctrl + C 终止,都会产生EXIT信号,从而触发删除临时文件。

注意,trap命令必须放在脚本的开头。否则,它上方的任何命令导致脚本退出,都不会被它捕获。

如果trap需要触发多条命令,可以封装一个 Bash 函数。

function egress {
  command1
  command2
  command3
}

trap egress EXIT

六、参考链接

(完)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • TF-IDF与余弦相似性的应用(一):自动提取关键词

    这个标题看上去好像很复杂,其实我要谈的是一个很简单的问题。 有一篇很长的文章,我要用计算机提取它的关键词(Automatic Keyphrase extract...

    ruanyf
  • Unicode与JavaScript详解

    上个月,我做了一次分享,详细介绍了Unicode字符集,以及JavaScript语言对它的支持。下面就是这次分享的讲稿。 ![](/blogimg/asset/...

    ruanyf
  • 防止网页被嵌入框架的代码

    最近,国内开始流行另一种流氓行为:使用框架(Frame),将你的网页嵌入它的网页中。 比如,有一家网站号称自己是"口碑聚合门户",提供全国各个网上论坛的精华内容...

    ruanyf
  • Linux 下卸载MySQL 5

        对于在Linux下通过rpm方式的mysql,我们可以通过移除这些rpm包以及删除项目的目录来达到卸载的目的。本文演示了在SUSE Linux 10下下...

    Leshami
  • 现实黑镜:将死去好友复活为AI

    大数据文摘
  • 鹅厂女专家:用“爱折腾”实现跨界之美

    毕业20+年,加入腾讯13年,三个部门,5个岗位,Alicemeng说这是因为自己“爱折腾”,而职业发展也在这不停的“折腾”中变得更加清晰起来。

    Techeek
  • 搞 Java 的年薪 40W 是什么水平?

    不知不觉已经工作 5 年了,一路走来磕磕碰碰但总算有了自己的一点小体会。对于一个 Java 开发人员来说,到了 5 年的关键节点,需要掌握哪些知识点呢?经过我自...

    范蠡
  • Office 2016下载安装与激活教程

    首先下载office professional plus 2016办公软件。 下载地址:

    Dabelv
  • 聊聊我的知识体系

    不知不觉树义已经工作 5 年了,一路走来磕磕碰碰但总算有了自己的一点小体会。对于一个 Java 开发人员来说,到了 5 年的关键节点,需要掌握哪些知识点呢?经过...

    陈树义
  • 聊聊我的知识体系

    不知不觉已经工作 5 年了,一路走来磕磕碰碰但总算有了自己的一点小体会。对于一个 Java 开发人员来说,到了 5 年的关键节点,需要掌握哪些知识点呢?经过我自...

    Java团长

扫码关注云+社区

领取腾讯云代金券