Eu pensei isso a
e a/.
é o mesmo caminho. No entanto, descobri queCPesincronizar novamentecopie o conteúdo do diretório em vez do próprio diretório quando /.
for adicionado ao caminho de origem. Eu também tentei a/inner/..
; isso também funcionou.
$ cp -r a b # Copies dir a into dir b.
$ cp -r a/. b # Copies files from dir a into dir b.
$ cp -r a/inner/.. b # Also copies files from dir a into dir b.
$ cd a && cp -r . ../b # One more way to copy inner files.
Eu entendo que isso é útil. Mas estou um pouco confuso porque parece que esse recurso quebra os padrões.
Como é que isso funciona? Esse recurso está documentado em algum lugar? Este é um recurso do sistema operacional,CPou festa?
Responder1
Eu entendo que isso é útil. Mas estou um pouco confuso porque parece que esse recurso quebra os padrões.
CPo comportamento ao copiar recursivamente de a/.
para b
é perfeitamente consistente com seu comportamento "normal".
Por padrão,CP's não cria diretórios pais. Isto pode ser modificado com opaistrocar:
--parents
use full source file name under DIRECTORY
Mas o que isso significa?
Isso significa que enquanto o comando
cp --parents -r some/path/to/source dest
copiará o conteúdo do diretório de origem para dest/some/path/to/source
o comando
cp -r some/path/to/source dest
copiará o conteúdo do diretório de origem para dest/source
.
Da mesma forma, o comando
cp -r some/path/to/source/. dest
copiará o conteúdo do diretório de origem para dest/.
, que é apenas dest
.
Eu pensei
a
ea/.
é o mesmo caminho.
a
ea/.
éo mesmo caminho. Mas como argumento paraCP, é apenas uma string.
Observe que os comandos
cp --parents -r some/path/to/source dest
e
cd some/path/to && cp --parents -r source dest
também se comportará de maneira diferente.
A respeito
cp -r a/inner/.. b
? Levando em consideração sua explicação, ele não deveria copiar os arquivosb/..
(ou seja, para o diretório atual)?
Bem, sim. Esta é uma exceção.
Pelo menos na versão GNU doCP, há um caso especial para o ..
nome base.
if (parents_option)
{
[removed]
}
else
{
char *arg_base;
/* Append the last component of 'arg' to 'target_directory'. */
ASSIGN_BASENAME_STRDUPA (arg_base, arg);
/* For 'cp -R source/.. dest', don't copy into 'dest/..'. */
dst_name = (STREQ (arg_base, "..")
? xstrdup (target_directory)
: file_name_concat (target_directory, arg_base,
NULL));
}
A motivação parece ser evitar copiar fora da pasta de destino, o que – embora perfeitamente consistente comCPo comportamento de em todos os outros casos – é um pouco contra-intuitivo e pode ter consequências desagradáveis.
Afinal, não acho que alguém esperaria o comando
cp -r .. ~
para afetar arquivos fora de seu diretório pessoal...
Responder2
$ mkdir a b a/inner
$ touch a/a{1..3} b/b{1..3}
$ ls -R
.:
a b
./a:
a1 a2 a3 inner
./a/inner:
./b:
b1 b2 b3
$ cp a b
cp: omitting directory ‘a’
$ cp a/. b
cp: omitting directory ‘a/.’
$ cp a/inner/.. b
cp: omitting directory ‘a/inner/..’
$ cd a && cp . ../b
cp: omitting directory ‘.’
$ cd ..
$ ls -R
.:
a b
./a:
a1 a2 a3 inner
./a/inner:
./b:
b1 b2 b3
Nenhuma das coisas que você diz acontece, realmente acontece. Os quatro cp
comandos não fazem nada. Talvez você tenha um alias para cp
carregado. Você pode verificar isso com alias cp
.
Responder3
A propósito rsync(1)
, leia seu manualcom cuidado. Ele usa algumas convenções incomuns para significar "o conteúdo do diretório" versus "o diretório e seu conteúdo".
Para cp(1)
e outros comandos do Linux, nonúcleonível a
e a/.
até mesmo a/inner/..
referem-se exatamente ao mesmo diretório. Isso não significa que o aplicativo não possa analisá-los por si mesmo e dar-lhes significados diferentes, mas é mais fácil simplesmente enviar a string para o kernel, que fará a coisa certa.
Responder4
Se bem me lembro, acredito no . neste caso funciona de forma semelhante a um arquivo *. Em essência, um caractere curinga.