Linux临时文件:/tmp、/var/tmp与mktemp
最近因为工作需要,需要写一些脚本。脚本中经常需要创建一个临时文件,保存一些内容,然后删除。可能看着很简单,但是我们往往需要考虑如下几个问题:
- 文件重名
- 使用结束后清理
- ……
所以,本文主要介绍了如何在Linux
优雅地创建临时文件
1. /tmp目录
Linux
中的/tmp
目录被称为临时目录,即用于存储用户的临时性的文件,亦经常被程读写用户存储临时性数据。
之所以称为是临时目录,是因为在绝大多数Linux
发行版中,/tmp 目录默认清理10天未用的文件,并且系统重启会清空目录。
A. 特点
下面是一些关于 Ubuntu 中 /tmp
目录的特点:
- 全局访问:
/tmp
目录是全局可访问的,任何用户都可以在其中读取和写入文件。 - 临时性质:
/tmp
目录中的文件被视为临时文件,不会被长期保存。它们通常在系统重启或定期任务运行时会被清理。 - 权限设置:在 Ubuntu 中,默认情况下,
/tmp
目录的权限设置为 1777(即 rwxrwxrwt)。这意味着所有用户都有读、写和执行的权限,但只有文件的所有者才能删除文件。 - 自动清理:Ubuntu 使用
systemd-tmpfiles
服务来管理/tmp
目录的自动清理。根据默认配置,systemd-tmpfiles
会在系统启动时清理/tmp
目录中的过期文件。
最后,虽然/tmp
目录下的临时文件目录中的文件可能只有几KB大小,但是/tmp
目录还是有被打满的可能的。
对于一般的操作系统而言,如果想填满整个/tmp
目录,可能得需要上百万个临时文件。但是如果你的机器上只运行着单个用户,并且机器会时常重启,那么就没必要担心了
如果你是一个服务器的管理员,这台服务器又运行着成百上千个其他用户,那么临时目录被填满的可能就会大大增加。越来越多的临时文件,会慢慢填满整个磁盘空间,最终会影响整个服务器的稳定。
2. /var/tmp目录
除了/tmp
目录以外,/var/tmp
目录也用于存储临时文件。但是注意,和/tmp
目录不同,在绝大多数Linux
发行版中,/var/tmp 目录默认清理30天未用的文件。
3. tempfile命令
上面我们介绍到,/tmp
目录的权限是任何人可读可写可执行。所以我们在/tmp
创建的任何文件都可以被其他人读写。如果我们手动在/tmp
目录下新建文件的话,还需要手动修改权限,就比较麻烦。
为此,Linux
提供了一个特殊命令可以用来创建临时文件:mktemp
。
A. 简介
mktemp
命令可以在/tmp
目录中创建一个唯一的临时文件。该命令会创建这个文件,并且自动设置文件的权限。
mktemp
命令会将文件的读和写权限分配给文件的属主,并将你设成文件的属主。一旦创建了文件,你就在脚本中有了完整的读写权限,但其他人没法访问它(当然,root
用户除外)
B. 在CWD中创建临时文件
默认情况下,mktemp
会在当前工作目录下创建一个文件。要用mktemp
命令在当前目录中创建一个临时文件,只需要指定一个文件名模板就行了。文件名模板可以包含任意文本文件名。
例如:
mktemp testing.XXXXXX
ls testing*
可以看懂,文件名模板中的X
被替换为了随机的字母。因此,每次运行该命令创建的文件的文件名都不同,从而避免了临时文件重名问题。
for ((i=0; i < 5; i++)); do mktemp testing-1.XXXXXX;done
需要注意的是,mktemp
命令会把文件名输出到stdout
上
C. 在/tmp目录创建临时文件
如果在CWD
中创建临时文件,那么就需要手动删除,就比较麻烦。所以如果能够直接将临时文件创建在/tmp
目录下,那么临时文件就会被清除,就很方便。
为此,mktemp
命令的-t
选项会强制mktemp
命令来在系统的临时目录来创建该文件。在用这个特性时,mktemp
命令会返回用来创建临时文件的全路径,而不是只有文件名。
for ((i=0; i < 5; i++)); do mktemp -t testing-in-tmp.XXXXXX; done
ls /tmp/testing-in-tmp.*
D. 创建临时目录
mktemp
命令的-d
选项告诉mktemp
命令来创建一个临时目录而不是临时文件。这样你就能用该目录进行任何需要的操作了,比如创建其他的临时文件。
mktemp -d temp_dir.XXXXXX
ls -al . | grep temp
-d
选项可以和-t
选项结合使用,从而在/tmp
目录下创建临时目录
mktemp -t -d temp_dir.XXXXX
ls -al /tmp | grep temp
E. 在脚本中使用mktemp命令
因为mktemp
命令会返回文件的名称和路径,因此在脚本中使用这个命令就非常方便。使用变量保存临时文件的名称即可
vim test.sh
然后编辑如下内容:
#!/bin/bash
# creating and using a temp file
tempfile=$(mktemp test.XXXXXX)
# 将文件描述符3绑定到该临时文件中
exec 3>$tempfile
echo "This script writes to temp file $tempfile"
echo "This is the first line" >&3
echo "This is the second line." >&3
echo "This is the last line." >&3
# 删除绑定
exec 3>&-
echo "Done creating temp file. The contents are:"
cat $tempfile
rm -f $tempfile 2> /dev/null
运行该脚本,查看效果:
chmod +x test.sh
./test.sh