Qual é a diferença entre os seguintes comandos?
mv foo bar
mv foo/ bar/
mv foo/ bar
mv foo bar/
Ou não há diferença? Ou depende do comando que está sendo usado? Pense, por exemplo, que li que o comportamento do rsync muda um pouco dependendo da versão que você usa. Alguém tem uma boa explicação para que eu não precise mais adivinhar e sinta que sei o que estou fazendo?
Responder1
Muitos utilitários Unix tratam os links simbólicos de maneira diferente, dependendo se há uma barra final.
Esse comportamento é descrito noDocumentação do link simbólico POSIXe também é mencionado noDocumentação do GNU coreutils.
Basicamente, a barra final significa seguir (ou "desreferenciar") o link simbólico.
Por exemplo, no código abaixo, dirlink
significa o link simbólico, mas dirlink/
significa o diretório para o qual o link simbólico aponta. rm
não removerá um diretório a menos que você diga rm -r
, mas rm
sem opções removerá com prazer um link simbólico.
$ mkdir dir
$ ln -s dir dirlink
$ ls -l
total 4
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:26 dir
lrwxrwxrwx 1 mikel mikel 3 2011-02-02 22:26 dirlink -> dir
$ ls -l
total 4
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:26 dir
lrwxrwxrwx 1 mikel mikel 3 2011-02-02 22:26 dirlink -> dir
$ rm dirlink/
rm: cannot remove `dirlink/': Is a directory
$ rm dirlink
$ ls -l
total 4
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:26 dir
Também é útil para visualizar as permissões de um diretório, sem ter que se preocupar se o diretório é um diretório real ou apenas um link simbólico para um diretório.
$ ls -ld dirlink
lrwxrwxrwx 1 mikel mikel 3 2011-02-02 22:46 dirlink -> dir
$ ls -ld dirlink/
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:46 dirlink/
e ainda funciona para diretórios regulares:
$ ls -ld dir
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:46 dir
$ ls -ld dir/
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:46 dir/
Outro exemplo é o find
comando. Se path
você pedir para pesquisar for um link simbólico, ele não seguirá o link simbólico por padrão, o que significa que apenas processa o link simbólico. Adicionar uma barra final faz com que o link simbólico seja tratado como o diretório para o qual o link aponta.
$ find dir
dir
dir/file
$ find dirlink
dirlink
$ find dirlink/
dirlink/
dirlink/file
(algumas versões de find têm uma opção -follow
ou -L
, mas isso faz com que siga todos os links simbólicos, não apenas o primeiro)
No caso de rsync
, se você deve anexar uma barra depende se você deseja que o diretório que está copiando seja um subdiretório ou não.
$ mkdir dir
$ touch dir/file
$ rsync -r dir dir.bak
$ find .
.
./dir
./dir/file
./dir.bak
./dir.bak/dir
./dir.bak/dir/file
$ rm -r dir.bak
$ rsync -r dir/ dir.bak
$ find .
.
./dir
./dir/file
./dir.bak
./dir.bak/file
Em outras palavras:
rsync dir dir.bak
copiadir
paradir.bak
, fazendodir
dentrodir.bak
rsync dir/ dir.bak
copia todo o conteúdo dedir
, sem fazerdir
dentrodir.bak
Responder2
Como jsalonen já disse, esses comandos realmente têm resultados idênticos se foo
e bar
forem, de fato, diretórios.
No entanto, se foo
e bar
não forem diretórios, o comando falhará se você anexar uma barra final e terá êxito se não o fizer. O problema é que, se o comando for bem-sucedido, provavelmente não terá o resultado pretendido. Na verdade, você pode até perder dados se foo
houver bar
arquivos ( bar
seriam sobrescritos).
Se sua intenção é especificar diretórios e não arquivos, então vocêdeveuse uma barra final, porque torna o comando mais robusto: se a expectativa de que foo
ou bar
são diretórios falhar, o comando falhará normalmente, em vez de ter resultados inesperados.
Além disso, alguns comandos (raros) se comportam de maneira diferente dependendo da presença de uma barra final, mesmo com diretórios (um exemplo é rsync
).