返回首页 两个月精通 Shell 脚本

shell 学习四十三天----临时性文件的建立与使用

临时性文件的建立与使用

虽然使用管道可以省去建立临时性文件的需求,不过有时临时性文件还是派得上用场的。linux 不同于其他的操作系统的地方就是:他没有那种将不再需要的文件设法删除的做法。反倒是提供了两个特殊目录:/tmp/var/tmp(旧系统是 /usr/tmp),这些文件可入场被存储,当他们未被清理干净时也不会弄乱一般的目录。大部分系统上的 /tmp 都会在系统开机时清理,不过 /var/tmp 下的在重启时仍需存在,因为有些文字编辑程序,会将他们的备份文件放在这里,从而系统损毁后可以用来恢复数据。

因为 /tmp 使用频繁,有些系统就会将他们放在常驻内存型的文件系统里,以便快速访问。

$df /tmp
Filesystem     1K-blocks   Used Available Use% Mounted on
/dev/sda3        1032088 262608    717052  27% /

将文件系统放在替换空间 (swap) 区域里,表示它存在与内存中,直到内存资源被使用得剩很少时,部分信息才会写入替换空间。

为确保临时性文件会在任务完成时删除,编译语言的程序员可以先开启文件,再下达 unlink() 系统调用。

$$ 变量

使用 $$ 变量可以获取 shell 本身的 PID。

案例:
$echo $$
1736

使用 $$ 变量构建临时性文件名的一部分。要解决完整临时性文件名发生此问题的可能性,可使用环境变量覆盖目录名称,通常是 TMPDIR。另外,应该使用 trap 命令,要求在工作完成时删除临时性文件。因此,常见的 shell 脚本起始如下:

umask 077                   #删除用户以外其他人的所有访问权
TMPFILE=$(TMPDIR-/tmp)/myprog.$$    #产生临时文件
trap ‘rm -f $TMPFILE’ EXIT #完成删除临时性文件

mktemp 程序

因为使用 /tmp/myprog.$$ 这样的文件名太好猜了,所以就有了 mktemp 命令。 在进行 shell 脚本程序设计时,经常需要生成临时文件,使用 mktemp 命令即可满足这样的要求,且保证了文件的安全性。

语法:

mktemp [-qu] [文件名参数]

有的系统是没有 mktemp 命令的,这时我们需要给 mktemp 打补丁,以使它包含 tempfile 包:

patch -Np1 -i ../mktemp-1.5-add_tempfile-2.patch

编译 mktemp

./configure --prefix=/usr --with-libc

配置选项的含义:

--with-libc 这个使得 mktemp 程序从系统的 C 库中使用 mkstepmkdtemp 的功能。

编译软件包:

make

安装软件包:

```make install make install-tempfile


**主要参数**

参数 作用 -q 执行时若发生错误,不会显示任何信息 -u 暂存文件会在 mktemp 结束前先行删除 -V 显示版本信息


案例:  

$mktemp tmp.XXX tmp.DSH $ mktemp tmp.XXX tmp.hEc $ mktemp tmp.XXX tmp.7yi

分析:点号后面的三个大写字母 XXX 代表了三个随机数。

$ ll -rw------- 1 root root 0 7 月 12 18:43 tmp.7yi -rw------- 1 root root 0 7 月 12 18:43 tmp.DSH -rw------- 1 root root 0 7 月 12 18:43 tmp.hEc

**`/dev/random` 与 `/dev/urandom` 特殊文件**

这两个文件都是用来产生随机数的。他们产生随机数的原理是利用当前系统的熵池来计算出一定数量的随机比特,然后将这些比特作为字节流返回。熵池就是当前系统的环境噪音,熵指的是一个系统的混乱程度,系统噪音可以通过很多参数来评估,如内存的使用,文件的使用,文件的使用量,不同类型的进程数量等等。如果当前环境噪音变得不是很剧烈或者当前环境噪音很少,日过刚开机的时候,而当前需要大量的随机比特,这时产生的随机数的随机数效果就不是很好了。

这就是为什么会有 `/dev/urandom` 和 `/dev/random` 这两种不同的文件,后者在不能产生新的随机数时会阻塞程序,而前者不会 (ublock),当然产生的随机数效果就不太好了,这对加密解密这样的应用来说不是一种很好的选择。`/dev/random` 会阻塞当前的程序,知道根据熵池产生新的随机字节之后才返回,所以使用 `/dev/random` 比使用 `/dev/urandom` 产生大量随机数的速度要慢。

案例:

$dd if=/dev/random of=random.dat bs=1024b count=1 记录了 0+1 的读入 记录了 0+1 的写出 128 字节 (128 B) 已复制,0.000356299 秒,359 kB/ 秒 $ dd if=/dev/urandom of=random.dat bs=1024b count=1 记录了 1+0 的读入 记录了 1+0 的写出 524288 字节 (524 kB) 已复制,0.226209 秒,2.3 MB/ 秒



分析:`/dev/random` 产生随机数的速度要慢,而且产生的量有限,但是产生随机数的质量好。