sed
cria um arquivo temporário, grava a saída nesse arquivo e renomeia o arquivo temporário por cima do original.
Você pode assistir ao que acontece 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 +++
Isso registra todas as operações de arquivo sed
efetuadas: cria um novo arquivo (com segurança O_CREAT|O_EXCL
), grava os dados nele e depois move-os de volta ao topo do meu arquivo original a
.
sed -i
aceita um sufixo para usar como backup e, nesse caso, move o original primeiro (em vez de renomear por cima). Esse argumento é obrigatório na maioria dos BSDs sed
. Nesse caso, há um breve momento em que não há nenhum arquivo com o nome correto no diretório.
perl
nas versões recentes abre o arquivo de entrada, exclui-o e cria um novo arquivo com o mesmo nome:
open("a", O_RDONLY) = 3
unlink("a") = 0
open("a", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
Quando você exclui ( unlink
) um arquivo que você já abriu, você mantém o acesso a ele enquanto mantiver o controle, para que ele continue lendo os dados do arquivo excluído. Dessa maneira, perl
grava diretamente no arquivo de saída, em vez de em um arquivo temporário: nenhum arquivo adicional é criado, mas se você ler o arquivo durante o processo, obterá conteúdo parcial, ao contrário sed
da abordagem. Também há um breve momento em que não há arquivo com o nome correto, que está no início do processo e não no final (como em sed -i .bak
).
Ambos sed
e perl
irão:
- Substitua um link simbólico por um arquivo comum.
- Quebrar links físicos.
- Preserve a propriedade do grupo, se possível.
- Crie o arquivo com o seu grupo padrão (ou o grupo do diretório pai, se esse diretório tiver o
setgid
bit), se pertencesse a um grupo em que você não pertence e não é root.
- Preserve a propriedade do arquivo se você for root.
- Preservar permissões básicas.
- Preservar
setuid
e setgrp
bits, se o grupo resultante for o mesmo que o grupo em que foi iniciado.
- Preserve a parte pegajosa.
- Não preserve xattrs.
sed
vai:
- Preservar ACLs (no Linux; não conheço outras pessoas) .
perl
vai:
O acima é verdade no Linux com GNU sed
e Mac OS X (derivado do FreeBSD) sed
.