O comportamento é um resultado lógico do algoritmo documentado para cp -R
. Veja POSIX , passo 2f:
The files in the directory source_file shall be copied to the directory dest_file, taking the four steps (1 to 4) listed here with the files as source_files.
.
e ..
são diretórios, respectivamente, o diretório atual e o diretório pai. Nenhum deles é especial no que diz respeito ao shell, portanto, nenhum deles está preocupado com a expansão (o que evita problemas com o shell que está expandindo arquivos ocultos ou não). src/.
é o diretório atual dentro de src
, que é src
; src/src_dir/..
é o diretório pai de src_dir
, que é novamente src
. Portanto, de fora de src
, se src
for um diretório, especificar src/.
ou src/src_dir/..
como o arquivo de origem para cp
será equivalente e copiar o conteúdo de src
.
O ponto de especificar src/.
é que ele falhará se src
não for um diretório (ou link simbólico para um diretório), enquanto src
não. Ele também copiará o conteúdo de src
, sem copiar o próprio src
; isso corresponde à documentação também:
If target exists and names an existing directory, the name of the corresponding destination path for each file in the file hierarchy shall be the concatenation of target, a single slash character if target did not end in a slash, and the pathname of the file relative to the directory containing source_file.
Portanto, cp -R src/. dest
copia o conteúdo de src
para dest/.
(o arquivo de origem é .
em src
), enquanto cp -R src dest
copia o conteúdo de src
para dest/src
(a origem o arquivo é src
).
Outra maneira de pensar nisso é comparar a cópia src/src_dir
e src/.
, em vez de comparar src/.
e src
. .
se comporta como src_dir
no primeiro caso.