sed
crea un archivo temporal, escribe el resultado en ese archivo y luego cambia el nombre del archivo temporal sobre la parte superior del original.
Puedes ver lo que sucede usando 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 +++
Esto registra todas las operaciones de archivo sed
: crea un nuevo archivo (de forma segura con O_CREAT|O_EXCL
), escribe los datos en él y luego lo mueve de nuevo sobre la parte superior de mi archivo original a
.
sed -i
acepta un sufijo para usar como copia de seguridad y, en ese caso, primero quita el original (en lugar de renombrarlo en la parte superior). Ese argumento es obligatorio en la mayoría de los BSD sed
. En este caso, hay un breve momento en el que no hay ningún archivo con el nombre correcto en el directorio.
perl
en versiones recientes abre el archivo de entrada, luego lo elimina y crea un nuevo archivo con el mismo nombre:
open("a", O_RDONLY) = 3
unlink("a") = 0
open("a", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
Cuando elimina ( unlink
) un archivo que ya tiene abierto, conserva el acceso al mismo mientras mantenga el control, para que pueda seguir leyendo los datos del archivo eliminado. De esta manera, perl
escribe directamente en el archivo de salida, en lugar de hacerlo en un archivo temporal: no se crea ningún archivo adicional, pero si lee el archivo durante el proceso, obtendrá contenido parcial, a diferencia sed
del enfoque. También hay un breve momento en el que no hay un archivo con el nombre correcto, que se encuentra al comienzo del proceso en lugar de al final (como en sed -i .bak
).
Ambos sed
y lo perl
harán:
- Reemplace un enlace simbólico con un archivo ordinario.
- Romper enlaces duros.
- Preservar la propiedad del grupo si es posible.
- Cree el archivo con su grupo predeterminado (o el grupo del directorio principal si ese directorio tiene el
setgid
bit) si era propiedad de un grupo en el que no está y no es root.
- Preserve la propiedad del archivo si es root.
- Preservar los permisos básicos.
- Conservar
setuid
y setgrp
bits, si el grupo resultante es el mismo que el grupo en el que comenzó.
- Preserve la parte pegajosa.
- No preservar xattrs.
sed
será:
- Preserve las ACL (en Linux; no sé sobre otros) .
perl
será:
Lo anterior es cierto en Linux con GNU sed
y Mac OS X con su (derivado de FreeBSD) sed
.