Segundo man cp
, usar cp -P * foo/
significa que nenhum link simbólico será seguido:
-P
: Nenhum link simbólico é seguido. Este é o padrão se a-R
opção for especificada.
Mas como copiar arquivos da mesma forma, ou seja, sem seguir links simbólicos, usando qualificadores glob Zsh e sem usar -P
? Preciso usar cp *(.) foo/
ou preciso usar cp *(-.) foo/
em vez disso?
De Quais são as diferenças práticas entre Bash e Zsh? em Pergunte diferente:
foo*(.)
: apenas correspondência de arquivos regularesfoo*
e links simbólicos para arquivos regulares, não diretórios e outros arquivos especiais.foo*(-.)
: apenas correspondência de arquivos regularesfoo*
, não links simbólicos e outros arquivos especiais.
Parece que a resposta é foo*(-.)
, mas não tenho certeza e realmente quero descobrir essas coisas.
zsh 5.9 (x86_64-apple-darwin23.0)
cp -P -- * foo/
(Eu adicionei a falta--
sem a qual os arquivos começando com-
poderiam ser tratados como opções porcp
) copiaria todos os arquivos parafoo/
. Para arquivos do tipo symlink , isso copiaria o link simbólico (sem alterar o destino do link simbólico, o que significa que o link copiado provavelmente se tornará inválido se não for para um caminho absoluto ou para um arquivo no mesmo diretório).Falhará em arquivos do tipo diretório que
cp
não são copiados sem a-R
opção. Mesmo assim,-R
ele falharia porfoo
si mesmo, poiscp
se recusaria a copiá-lo para si mesmo.cp -- *(.) foo/
copiará apenas arquivos do tipo regular (conforme selecionado pelo.
qualificador glob ), com exclusão de qualquer outro tipo de arquivo, incluindo link simbólico, diretório, fifo, dispositivo... Portanto,-P
as-R
opções são irrelevantes aqui.cp -- *(-.) foo/
também copia os arquivos do tipo regular , mas desta vez, o tipo de arquivo é verificado após a resolução do link simbólico (graças ao-
qualificador), portanto, ele também copiará links simbólicos que podem ser determinados para eventualmente resolverem arquivos do tipo regular . Para aqueles sem-P
, a cópiafoo/
será um arquivo normal com o mesmo conteúdo daquele para o qual o link simbólico resolve.De qualquer forma, globs e seus qualificadores glob não copiam arquivos, eles são apenas uma ferramenta shell para ajudá-lo a selecionar arquivos para passar aos comandos. Para copiar arquivos, você normalmente usa
cp
¹.Aqui, se você deseja copiar todos os arquivos não ocultos no
foo
estado em que se encontram (copiando links simbólicos como links simbólicos, mesmo que isso signifique torná-los links quebrados e o máximo de metadados possível), excluindo aqueles do tipo directory , você faria:Usando o
/
qualificador (seleciona arquivos do tipo directory ) negado com^
.Para copiar todos os arquivos, incluindo os ocultos e diretórios (incluindo seu conteúdo completo recursivamente):
(o
D
qualificador, como adotglob
opção, evita o salto de arquivos ocultos, também conhecidos como dotfiles).Onde excluímos explicitamente
foo
da lista de arquivos a serem copiados para evitarcp
o erro de. Observe que, com algumascp
implementações,-P
é o padrão quando-R
é passado, mas esse não é o caso de todascp
as implementações e não é especificado por POSIX .Não sei sobre
cp
a implementação do próprio macos, mas com ascp
implementações do GNU, busybox e toybox,cp -RPp . foo/
também funciona exceto pelo erro de copiarfoo
para si mesmo.Com GNU
cp
, isso ainda copia ofoo
diretório em si, mas não seu conteúdo. Com acp
implementação deast-open
, isso entra em uma cópia de recursão infinitafoo
e todo o seu conteúdo emfoo
.¹ Embora você também possa usar
pax
,tar
, ou até mesmo alguns componentes internos do shell , como o array associativo especial do zsh ou alguns de seus componentes internoscpio
, como // / com redirecionamentos.rsync
$mapfile
read
print
sysread
syswrite