Para copiar um diretório para outro diretório, o primeiro diretório deve ser escrito sem a barra final:
# example 1
# this command will copy dir1 to dir2
# (dir2 is preexisting)
cp -Rip dir1 dir2/
Caso contrário, o comando copiará o conteúdo do diretório e não o próprio diretório:
# example 2
# this command will copy dir1 contents to dir2
# (dir2 is preexisting)
cp -Rip dir1/ dir2/
Eu entendo a diferença entre dir1
e dir1/
aqui, e a diferença entre como esses dois comandos se comportam não me confunde.
Mas para copiar o diretório não para outro diretório, mas para o mesmo diretório onde está localizado atualmente, a barra final não fará nenhuma diferença. Por que?
# example 3
# any of these commands will make a dir1 copy
# (dir1-copy isn't preexisting)
cp -Rip dir1 dir1-copy/
cp -Rip dir1/ dir1-copy/
E outra questão intimamente relacionada. Por que não há diferença entre como mv dir1/ dir2/
e mv dir1 dir2/
trabalho? Em outras palavras, por que, em relação à barra final no final do diretório de origem, mv
segue a lógica do terceiro cp
exemplo, e não a lógica dos exemplos um e dois?
macOS 14.3.1, zsh 5.9 (x86_64-apple-darwin23.0)
A diferença de comportamento entre
cp -R dir1 dir2
ecp -R dir1/ dir2
é um recurso que foi adicionado ao FreeBSD na versão 5.4 . Pelo menos foi então que a seguinte frase foi adicionada ao manual para a descrição da-R
opção:É possível que esse comportamento fosse mais antigo e o 5.4 apenas preenchesse uma omissão na documentação. Não há nada sobre isso nas notas de versão 5.0 , 5.1 , 5.2 , 5.3 ou 5.4 . Eu não fui mergulhar na fonte.
Versões modernas do FreeBSD e macOS que possuem utilitários de linha de comando do FreeBSD mantiveram esse comportamento. Outros sistemas (GNU, BusyBox, OpenBSD, NetBSD ou qualquer outro compatível com POSIX) não possuem esse comportamento:
cp -R dir1/ dir2
ecp -R dir1 dir2
possuem exatamente o mesmo comportamento (exceto quandodir1
é um link simbólico:dir1/
faz com que o link seja seguido).O comportamento do FreeBSD pode ter sido inspirado no rsync, que tem a mesma distinção. Acho estranho que eles tenham feito uma mudança incompatível com versões anteriores que se desviou
É uma decisão de design estranha. Ou talvez não tenha sido uma decisão de design, mas um bug de implementação (analisando o caminho de origem e decidindo que a parte após a barra final é um componente do caminho) que eles decidiram chamar de recurso. Com o rsync, a barra final mantém seu comportamento mesmo quando o diretório de destino não existe.
Não deveria haver diferença (supondo que
dir1
não seja um link simbólico), então esse é apenas o estado normal das coisas.