sed
создает временный файл, записывает выходные данные в этот файл и затем переименовывает временный файл поверх оригинала.
Вы можете посмотреть, что происходит, используя strace
:
$ strace -e trace=file sed -i -e '' a
execve("/usr/bin/sed", ["sed", "-i", "-e", "", "a"], [/* 34 vars */]) = 0
<...trimmed...>
open("a", O_RDONLY) = 3
open("./sedxvhRY8", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
rename("./sedxvhRY8", "a") = 0
+++ exited with 0 +++
Это регистрирует все операции, sed
выполняемые с файлами : он создает новый файл (безопасно с ним O_CREAT|O_EXCL
), записывает в него данные и затем перемещает их обратно поверх моего исходного файла a
.
sed -i
принимает суффикс для использования в качестве резервной копии, и в этом случае он сначала удаляет оригинал (а не переименовывает поверх). Этот аргумент является обязательным в большинстве BSD sed
. В этом случае, существует короткое время, когда в каталоге нет файла с правильным именем.
perl
в последних версиях открывает входной файл, затем удаляет его и создает новый файл с тем же именем:
open("a", O_RDONLY) = 3
unlink("a") = 0
open("a", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
Когда вы удаляете ( unlink
) файл, который вы уже открыли, вы сохраняете доступ к нему до тех пор, пока сохраняете дескриптор, чтобы он мог продолжать чтение данных из удаленного файла. Таким образом, perl
записывается непосредственно в выходной файл, а не во временный файл: дополнительный файл не создается, но если вы прочитаете файл во время процесса, вы получите частичное содержимое, в отличие от sed
подхода, используемого в этом подходе. Также существует короткое время, когда нет файла с правильным именем, который находится в начале процесса, а не в конце (как в sed -i .bak
).
И так sed
и perl
будет:
- Замените символическую ссылку обычным файлом.
- Разорвать жесткие ссылки.
- Сохраните групповое владение, если это возможно.
- Создайте файл с вашей группой по умолчанию (или группой родительского каталога, если этот каталог имеет
setgid
бит), если он принадлежал группе, в которой вы не находитесь и не являетесь пользователем root.
- Сохраните право собственности на файл, если вы root.
- Сохранить основные разрешения.
- Сохранение
setuid
и setgrp
биты, если результирующая группа совпадает с группой, в которой она была начата.
- Сохраните липкий бит.
- Не сохранять xattrs.
sed
воля:
- Сохранить ACL (В Linux; я не знаю о других) .
perl
воля:
Вышесказанное верно для Linux с GNU sed
и Mac OS X с его (производным от FreeBSD) sed
.