其实,文件也可以truncate
现在觉得,时间的流逝速度和年龄确实是成正比的。也就是说,年纪越大,就会觉得空闲时间越来越少了~
因此,本blog都大半个月没更新了,呵呵。也不能老这么沉寂下去,今天来写点东西。
熟悉数据库的朋友们都知道,大多数数据库都有个truncate指令:truncate table xxx可以把xxx表里的所有数据都删掉,但是保留表结构。其实,在有任何数据库之前,UNIX系统里就有了truncate这个命令了,当然后面的*nix里都保留了这个。可以想像,系统里的truncate命令的操作对象肯定是文件,而且此命令不仅能把文件的数据删成0字节,还可以缩减(甚至扩大)文件至指定的大小(通过 -s 选项指定文件大小值),这对于那种日志头部有些不想删除的关键信息,但后面的部分又很多很杂的情况下很有用。对于普通的日志文件,我们要清理的时候通常可以执行 > log
来清除文件的内容(这样,log文件会变成0字节),但是如果清理的同时想保留原始日志的前面4K的信息,不用truncate就会很麻烦了。
truncate的用法还是通过实战来解释吧,如下:
lily@LLY ~$ echo -n 1234567 > txt lily@LLY ~$ cat txt 1234567lily@LLY ~$ lily@LLY ~$ truncate -s 4 txt lily@LLY ~$ cat txt 1234lily@LLY ~$ lily@LLY ~$ ls -l txt -rw-r--r-- 1 lily lily 4 10月 24 16:54 txt lily@LLY ~$ truncate -s 1M txt lily@LLY ~$ ls -l txt -rw-r--r-- 1 lily lily 1048576 10月 24 17:17 txt lily@LLY ~$ du txt 4 txt lily@LLY ~$ wc -c txt 1048576 txt |
这里还可以看到一个“奇怪”的现象,本来已经缩至4字节的文件,把它扩展成1M以后,ls 和 wc 的结果显示大小确实是1M,但是 du 的结果却发现大小还是4字节。这也是要注意的地方之一,这种文件称为“空洞文件”,也就是说,文件的部分内容并没有实际存在于硬盘上(即没有分配对应的inode),只是“声称”有1M的大小而已。对于不存在于硬盘上的那部分字节,如果去读的话,也是不会报错的,会读到全0的数据。
这也从另一个方面反映出ls等命令默认显示的是文件“声称”的大小,而du (disk use)默认显示的是真正的磁盘占用。这里是我以前的另外一个例子。
Shellexy 在 2010年10月24日 19:12 说:【 】
骨头哇,
ls -l 加参数 -s 就可以了
bones7456 在 2010年10月24日 19:26 说:【 】
是喽,所以我文中是“默认显示”。文末那个链接的文章里,也有说到过-s参数。
依云 在 2010年10月24日 19:46 说:【 】
那个不是4字节啦。du 默认单位是块 (block)。加参数 -h 才是字节什么的。
icyomik 在 2010年10月24日 20:06 说:【 】
呵呵,每次都学到新的知识。
tusooa 在 2010年10月24日 22:03 说:【 】
不用truncate也可以的.
cp -v /tmp/test{,.orig}
head -s4 /tmp/test.orig > /tmp/test
bones7456 在 2010年10月25日 09:29 说:【 】
这样不仅麻烦,而且不是原子操作,比如输出日志的进程可能还一直在频繁输出的,你这样就不方便了。何况,万一日志文件很大,没有磁盘空间来给你全量复制一份怎么办?这种情况很多,比如设置了磁盘使用90%告警,然后维护人员收到告警了,才去处理日志,想把几十G的日志复制一遍可不容易。
你这样的话,其实 head -c4 log > /tmp/log; mv /tmp/log log 更好,当然truncate还是方便多了。
tusooa 在 2010年10月27日 16:39 说:【 】
保留文件前3行:
● perl -i -e ‘$num = 0 ; while () { $num++; last if $num > 3; print; }’ /tmp/bash/svn/co-log
tusooa 在 2010年10月24日 22:05 说:【 】
head -c4 。写错了。。。
hfw_1987 在 2010年10月27日 15:34 说:【 】
也就是说,文件的部分内容并没有实际存在于硬盘上(即没有分配对应的inode)
=================
这句话有问题吧,一个文件对应一个inode,除非有硬链接,哪有没有分配对应inode的说法?
shan 在 2010年10月28日 09:16 说:【 】
学习了。
bones7456 在 2010年10月30日 10:08 说:【 】
哈哈,这个居然被当成了垃圾评论
runcoderen 在 2010年11月07日 08:55 说:【 】
学习了啊,平时一点一滴就是很大的收获了
ptubuntu 在 2010年11月09日 17:14 说:【 】
看的头都大起来了.我也好久没有更新了.
沧州seo 在 2010年11月14日 23:16 说:【 】
说实话 你说的这个我真的一点不懂,可不可以顺带点基础知识啊?
远走高飞 在 2010年11月16日 09:20 说:【 】
趁年轻时觉得空闲的时候多找点事情做。。
openboy 在 2010年11月21日 19:06 说:【 】
把你整个经验技巧分类翻了一遍。收获很多。感谢~喜欢折腾Ubuntu..
百度黑板报 在 2010年11月30日 03:44 说:【 】
不错~
就是truncate不是那么标准的命令 并不是所有的系统都默认会有
Learn Python The Hard Way 学习笔记(1) | oppih 在 2010年12月08日 20:19 说:【 】
[…] Shell中就有truncate方法哦,这是我GR上面读到的:其实,文件也可以truncate […]
ayanmw 在 2011年05月25日 16:16 说:【 】
或许 应该sync下再试试 修改文件要同步下。
Dig 在 2011年11月13日 09:41 说:【 】
truncate 是不是不能按行截取?我需要保留的绝大多数log都是可读的文本格式,按字符截取似乎不太靠谱,按行才是上策;
所以还是习惯用head/tail之类的