Eu tenho uma pasta que contém um certo número de arquivos que possuem links físicos (na mesma pasta ou em outro lugar) e quero desassociá-los, para que eles se tornem independentes e as alterações no conteúdo não afetem outro arquivo (a contagem de links se torna 1).
Abaixo, dou uma solução que basicamente copia cada link físico para outro local e depois o move novamente.
No entanto, esse método parece bastante grosseiro e propenso a erros, então eu gostaria de saber se existe algum comando que elimine o link de um arquivo para mim.
Resposta bruta:
Encontre arquivos com links físicos ( Editar : para também encontrar soquetes etc. que tenham links físicos, use find -not -type d -links +1
):
find -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.
Um método simples para desassociar um arquivo (copie-o para outro local e mova-o de volta):
Editar: Como o Celada disse, é melhor fazer um cp -p abaixo, para evitar a perda de carimbos de data e hora e permissões. Editar: Crie um diretório temporário e copie para um arquivo abaixo dele, em vez de sobrescrever um arquivo temporário, minimiza o risco de sobrescrever alguns dados, embora o mv
comando ainda seja arriscado (obrigado @Tobu). Editar: tente criar o diretório temporário no mesmo sistema de arquivos (@MikkoRantalainen).
# This is unhardlink.sh
set -e
for i in "$@"; do
temp="$(mktemp -d -- "${i%/*}/hardlnk-XXXXXXXX")"
[ -e "$temp" ] && cp -ip "$i" "$temp/tempcopy" && mv "$temp/tempcopy" "$i" && rmdir "$temp"
done
Portanto, para desassociar todos os links físicos ( Editar : alterado -type f
para -not -type d
, veja acima):
find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh
cp -i
opção, ele cuspiu algumas mensagens perguntando se deveria substituir ./fileXXXXXX
(o $temp
arquivo), mesmo que tmpfile deva dar nomes de arquivo exclusivos, portanto, é necessário seja algum tipo de condição de corrida ou o que seja, e com isso o risco de perder alguns dados.
unhardlink.sh
deve criar um diretório temporário dentro do mesmo diretório que contém o arquivo que precisa ser desvinculado. Caso contrário, sua chamada recursiva poderá se repetir dentro de outro sistema de arquivos e você acabará movendo as coisas além dos limites do sistema de arquivos porque seu diretório temporário está no diretório de trabalho atual. Eu acho que você poderia passar "$(dirname "$i")/hardlink-XXXXXX"
como argumento para mktemp.
fuse
sistema de arquivos, ele poderá realmente ser enviado path/to/hardlink-XXX
para uma mídia de armazenamento físico diferente path/to/original-file
, mas não há muito o que fazer sobre isso.