Eu tenho um comando que aceita um arquivo como argumento, modifica o arquivo e o grava no nome do arquivo especificado no segundo argumento. Vou ligar para esse programa modifyfile
.
Eu queria que ele funcionasse "no local", então escrevi um script de shell (bash) que o modifica para um arquivo temporário e depois o move de volta:
TMP=`mktemp`
modifyfile "$original" "$TMP"
mv -v "$TMP" "$original"
Isso tem o efeito colateral lamentável de destruir as permissões nesse arquivo. O arquivo é recriado com permissões padrão.
Existe uma maneira de dizer ao mv
comando para substituir o destino sem alterar suas permissões? Ou, alternativamente, existe uma maneira de salvar o usuário, grupo e permissões do original e restaurá-los?
fonte
rm "$TMP"
fazê-lo, mas parece fazer exatamente o que eu quero.mv
. Não vejo uma maneira de resolver esse problema.chown
funciona apenas como raiz.chmod
echgrp
pode ou não funcionar, dependendo das permissões do usuário. Nenhum deles copia outros atributos, como ACL ou atributos estendidos específicos do sistema de arquivos.Existem duas estratégias para substituir um arquivo por uma nova versão:
Crie um arquivo temporário com a nova versão e mova-o para o lugar.
Substitua o arquivo antigo no local.
Se você puder, use o método 1, mas primeiro replique os atributos do arquivo original com
cp -p --attributes-only
. Isso requer GNU coreutils (ou seja, Linux não incorporado ou ambientes suficientemente semelhantes ao Linux). Se o seucp
não tiver--attributes-only
, omita esta opção: funcionará, mas replicará os dados também.Se você não puder replicar os atributos do arquivo existente, por exemplo, porque você possui permissões de gravação, mas não o possui e deseja preservar o proprietário, apenas o método 2 é possível. Para minimizar o risco de perda de dados:
fonte
cp -p --attributes-only "$original" "$tmp"
não usará recursos para copiar o conteúdo do arquivo. Não consegui encontrar de qual versão esse argumento foi adicionado.cp
implementações.Após nossa discussão sobre a primeira resposta, proponho uma resposta diferente:
Observações:
$original
nomktemp
modelo para garantir que o arquivo temporário não seja colocado,/tmp
mas na mesma pasta que$original
. Acredito que, se/tmp
montado em um sistema de arquivos diferente, a operação não seria mais atômica.mktemp
agora é citado caso contenha espaço em branco.$()
vez de `` porque eu o considero mais limpo.ch{mod,own} --reference
são usados para transferir as permissões de$original
para$TMP
. Se alguém tiver ideias adicionais sobre quais metadados podem e devem ser transferidos, edite minha postagem e adicione-a.fonte