当命令的输出被重定向到文件时,在执行命令之前shell会创建或截断输出文件,任何想法cat foo> foo呢?
答案 0 :(得分:17)
在所有情况下,文件都会被截断。这是因为重定向由shell处理,它在调用命令之前打开文件进行写入。
cat foo > foo
shell截断并打开foo进行写入,将stdout设置为文件,然后执行["cat", "foo"]
。
GNU cat很聪明,拒绝将文件重定向到自身。它通过检查输入和输出文件描述符上的设备/ inode对来完成此操作;你可以在src/cat.c中阅读精彩的低级细节。它打印一条消息并退出。
BSD cat没有这样的安全性,但由于该文件已被截断,因此无需读取任何内容,无需编写内容,它将停止。
你可以通过追加而不是截断来增加一些东西。
echo hello > foo
cat foo >> foo
现在一切都是一样的,除了shell打开文件以便追加而不是截断它。
GNU猫会看到你在做什么并停止;该文件未受影响。
BSD cat进入循环并将文件附加到自身,直到磁盘填满为止。
答案 1 :(得分:4)
在Fedora 13上,这就是我所看到的
cat foo > foo
cat: foo: input file is output file
如果foo
之前包含任何内容,它就会消失。
答案 2 :(得分:2)
首先截断文件然后读取,因此该命令会截断文件。
当我试图执行它时,我收到了这个警告:
cat:test.txt:输入文件是输出文件
答案 3 :(得分:1)
Shell将截断,cat
显然会检查一个已命名的parm,但不会检查stdin
,如下所示,并且总是成功:
$ uname -a
Linux bar 2.6.18-164.15.1.el5PAE #1 SMP Wed Mar 17 12:14:29 EDT 2010 i686 i686 i386 GNU/Linux
$ dd if=/dev/urandom of=foo bs=1024 count=4
4+0 records in
4+0 records out
4096 bytes (4.1 kB) copied, 0.00334456 seconds, 1.2 MB/s
$ od -c foo |head -2
0000000 U 371 003 z 224 334 z K 236 221 k < c 256 !
0000020 % % 256 V \ 005 , 254 X 202 330 004 222 " 037 226
$ cat <foo >foo && od -c foo
0000000