Когда вывод команды перенаправляется в файл, выходной файл создается или усекается оболочкой перед выполнением команды, любая идея, что делает cat foo > foo?
В UNIX что "cat file1> file1 делает?"
Ответ 1
Во всех случаях файл обрезается. То потому что перенаправление обрабатывается оболочкой, которая открывает файл для записи перед вызовом команды.
cat foo > foo
Среда обрезает и открывает foo для записи, устанавливает stdout в файл, а затем execs ["cat", "foo"]
.
GNU cat умный и отказывается перенаправлять файл самому себе. Это делается путем проверки пары device/inode на входных и выходных дескрипторах файлов; вы можете прочитать замечательные низкоуровневые подробности в src/cat.c. Он печатает сообщение и завершает работу.
У BSD cat нет такой безопасности, но поскольку файл уже усечен, читать нечего, писать нечего, и он будет остановлен.
Вы можете немного подправить вещи, добавив вместо усечения.
echo hello > foo
cat foo >> foo
Теперь все одно и то же, за исключением того, что оболочка открывает файл для добавления вместо усечения.
GNU cat видит, что вы делаете и останавливаетесь; файл не тронут.
BSD cat переходит в цикл и добавляет файл к себе, пока ваш диск не заполнится.
Ответ 2
В Fedora 13 это то, что я вижу
cat foo > foo
cat: foo: input file is output file
Если foo
содержит что-либо ранее, оно исчезло.
Ответ 3
Сначала файл усекается, а затем читается, поэтому эта команда будет обрезать файл.
Когда я попытался выполнить его, я получил это предупреждение:
cat: test.txt: входной файл - это выходной файл
Ответ 4
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