Situação:
$ mkdir foo && touch foo/.test
$ cp foo/* .
zsh: no matches found: foo/*
(or bash : cp: cannot stat ‘foo/*’: No such file or directory)
Eu tenho um diretório cheio de pastas e arquivos ocultos. O que está acontecendo e qual é a solução?
dotglob
é traduzido paraglobdots
pelo zsh que é nome de opção inválida para o bash .Respostas:
Isenção de responsabilidade: Esta resposta lida especificamente com o Bash, mas muito disso se aplica à pergunta sobre padrões glob!
O caractere estrela (
*
) é um curinga. Há um certo conjunto de caracteres que ele substituirá e o primeiro caractere sendo um ponto (.
) não é um deles. Este é um caso especial apenas por causa do funcionamento dos sistemas de arquivos Unix, os arquivos que começam com um ponto são considerados "ocultos". Isso significa que ferramentas comocp
,ls
etc. não as "verão", a menos que seja explicitamente instruído a fazê-lo.Exemplos
Primeiro, vamos criar alguns dados de amostra.
Então agora temos o seguinte:
Agora vamos jogar alguns jogos. Você pode usar o comando
echo
para listar o que seria um caractere curinga (*
) específico para um determinado comando, como:Mudando o comportamento?
Você pode usar o comando
shopt -s dotglob
para alterar o comportamento do*
arquivo para que, além de arquivos comoregfile1
ele, também corresponda.dotfile1
.trecho da
bash
página de manualExemplo:
Você pode reverter esse comportamento com este comando:
Sua situação?
Para você, você está dizendo
cp
que deseja copiar todos os arquivos que correspondem ao padrão*
e que não existem arquivos.Ou você pode fazer isso se quiser tudo na
foo
pasta:Ou você pode ser explícito:
Uma forma mais compacta usando expansão de chaves em
bash
:A qualquer momento, você pode usar o
echo
truque para ver quais padrões de arquivo propostos (esse é o termo mais sofisticado para o qual a estrela faz parte).Aliás, se você deseja copiar um diretório de arquivos + outros diretórios, normalmente deseja fazer isso recursivamente, essa é a
-R
opção paracp
:fonte
shopt -s dotglob
,echo *
e fornece:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
normalmente não funcionará, poiscp
se recusará a copiarfoo
sobre si mesmo, você provavelmente quis dizercp -R foo/. .
. (note quecp -R
é o padrão).zsh
não inclui.
e..
na expansão de.*
. Além dissozsh
, se um padrão não corresponder, o comando será abortado (novamente com bastante sensibilidade); portanto, no caso geral,cp foo/{,.}* .
falhará se não houver arquivos ocultos ou não ocultos.shopt
não existe.Com
zsh
, a maneira típica é usar oD
qualificador glob (para incluir [D] ot arquivos):Observe que, com ou sem
D
, os zsh globs nunca incluem.
nem..
(como seria de esperar).fonte
O shell está tratando esses arquivos como ocultos quando resolve o
*
caractere, portantocp
, não recebe nenhum desses nomes de arquivo como argumentos.Você pode copiá-los especificando explicitamente
cp foo/.* .
fonte
Se o que você deseja fazer é copiar todos os arquivos e diretórios de um lugar para outro, você pode usar o
rsync
comando padrão . No exemplo que você fornece acima:copiará recursivamente todo o conteúdo de
foo
, incluindo arquivos ocultos e diretórios ocultos, no diretório atual. A barra final no final defoo/
é importante para o rsync; com ele apenas o conteúdo defoo
é copiado, sem ele o rsync também copiafoo
. Por exemplo:-Existem muitas outras opções disponíveis para ajustar o rsync, incluindo a cópia entre máquinas.
fonte
A resposta zsh de Stéphane Chazelas está correta para uma única expressão com um globo nela. No entanto, se você quiser defini-lo para todas as expressões por padrão, poderá usar
Coloque no seu
~/.zshrc
para torná-lo permanente.fonte