Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2315128
  • 博文数量: 527
  • 博客积分: 10343
  • 博客等级: 上将
  • 技术积分: 5565
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-26 23:05
文章分类

全部博文(527)

文章存档

2014年(4)

2012年(13)

2011年(19)

2010年(91)

2009年(136)

2008年(142)

2007年(80)

2006年(29)

2005年(13)

我的朋友

分类: LINUX

2007-03-28 15:46:57

将一个文件的内容翻一番, 也就是说, 如果它原来的内容是"abc", 现在让它变成 "abcabc".

当然, 莽夫型的:
cp file tmp_file
cat tmp_file >> file
细心的莽夫还会记得
rm tmp_file

这当然能工作, 但, 效率不高, 而且, 在这样的情况下会失败:
你的剩余空间只有 10M, 你的 file 也是 10M, 这样当你 cp file tmp_file
之后, 你的硬盘就无旋马之地了.

一知半解型的:
cat file file > file
然后他瞪大双眼发现 file里的内容已经血本无归

不死心型的:
cat file >> file
你的硬盘有多大, 你就得等多久.

似乎聪明的方法:
cat <(cat file) >> file
结果跟前者一样

希望分组命令或子SHELL能带来点什么的:
{ cat file file ; } > file
( cat file file ) > file

关键是shell在何时执行 > file, 在执行命令之前! 所以file的内容都没了.

我知道还有一种人会玩弄 exec <&- 之类的东西, 也许这可行

优雅的办法是
dd if=file of=file bs=$(stat -c %s file)c count=1 seek=1
但在这之前, 我这样做过:
dd if=file of=file bs=1c count=$(stat -c %s file) seek=$(stat -c %s file)
真正要COPY的字节数都是 bs * count, 但两者性能是天壤之别, 因为后者的写单位是1字符. 而前者的写单位是文件的当前大小. 注意即使当前文件已经很大了, 指定一个很大的数字作为写的单位却不会引起什么性能上的损失, 这是因为过大的写单位会被以系统最优的写单位分而治之.

关于dd容易搞错的一点是 数字后面跟c表示字节, 跟b表示block, 而不是byte
关于dd更容易搞错的一点是, 指定输出文件的偏移是用seek, 而指定输入文件的则是skip

幕后:
shell会首先处理 > file, 目的是为要启动的命令准备好正确的文件描述符, 只有这一步处理好重定向, 被执行的程序才会继承到正确的文件描述符, 所以这一步要先行.

对命令行上的 <(sub command)
shell要为它自动产生一个文件名, 用set -x后执行可以看到这个自动产生的文件名, 这个文件名当然不用用户手工去清除. 该文件的内容自然是command的输出结果, 但, 启动主命令时需不需要sub command已经完成? 命令说明问题:
cat <( echo 123; ps u; sleep 1; )

其输出是
123
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
zhao      1082  0.0  1.2  4524 1572 pts/0    S    22:03   0:00 -bash
zhao      1154  0.0  0.3  3584  400 pts/0    S    23:36   0:00 cat /dev/fd/63
zhao      1155  0.0  0.4  2536  620 pts/0    R    23:36   0:00 ps u
显然, 在子命令完成之前, 主命令已经被启动, 这正是为什么
cat <( cat file ) >> file
会陷入无限等待的原因, shell以追加方式打开 file, 然后另起一个进程执行sub command, 也就是这里的cat file, 同时主程序也被启动, 这样:

1. 主程序的cat 不断地从 /dev/fd/63 中读取内容, 而
2. /dev/fd/63 的内容由子命令cat file得来
3. 子命令cat file不断读取file的内容, 却怎么也读不到它的尾部, EOF, 这是因为
4. 主程序启动之前已经以追加方式打开了file, 所以主程序的cat 的输出源源不断地把内容送到file中去

这本质上是一个间接无穷递归, 跟 while(1); 类似

阅读(1093) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~