find -delete não exclui diretórios não vazios

32

O comando

$ find ~ -name .DS_Store -ls -delete

funciona no Mac OS X, mas

$ find ~ -name __pycache__ -type d -ls -delete

não - os diretórios são encontrados, mas não excluídos.

Por quê?

PS. Eu sei que posso fazer

$ find ~ -name __pycache__ -type d -ls -exec rm -rv {} +

a questão é por find -delete que não funciona.

sds
fonte

Respostas:

36

findO -deletesinalizador de funciona de maneira semelhante ao rmdirexcluir diretórios. Se o diretório não estiver vazio quando for atingido, ele não poderá ser excluído.

Você precisa esvaziar o diretório primeiro. Como você está especificando -type d, findnão fará isso por você.

Você pode resolver isso fazendo duas passagens: primeiro exclua tudo dentro de diretórios nomeados e __pycache__, em seguida, exclua todos os diretórios nomeados __pycache__:

find ~ -path '*/__pycache__/*' -delete
find ~ -type d -name '__pycache__' -empty -delete

Um pouco menos rigidamente controlado, mas em uma única linha:

find ~ -path '*/__pycache__*' -delete

Isso excluirá qualquer coisa da sua casa que tenha __pycache__como parte do seu caminho.

GnP
fonte
Na descoberta 4.4.2, esse último comando precisa ser find ~ -path '*/__pycache__*' -delete, ou provavelmente find ~ -path '*/__pycache__/*' -o -name __pycache__ -deleteestar seguro.
precisa saber é o seguinte
3
@ naught101, deve ser find ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -deletecomo e tem precedência sobre ou .
Stéphane Chazelas
6

Existem algumas razões possíveis para isso.

1) Você disse para excluir apenas os diretórios ( -type d), e esses diretórios ainda têm arquivos dentro deles.

2) Seus diretórios contêm apenas outros diretórios; portanto, -type deles resolverão o problema do conteúdo. No entanto, você está usando o OS-X, que é amplamente baseado no FreeBSD, e o FreeBSD, findpor padrão, processará o diretório antes de seu conteúdo.
No entanto, -depthexiste a opção de resolver esse problema, informando findpara processar o diretório após seu conteúdo.

find ~ -name __pycache__ -type d -ls -delete -depth

Esse problema não existe no linux porque a -deleteopção habilita implicitamente -depth.

 

FreeBSD man 1 find:

 -depth  Always true; same as the non-portable -d option. Cause find to
   perform a depth-first traversal, i.e., directories are visited in
   post-order and all entries in a directory will be acted on before
   the directory itself. By default, find visits directories in
   pre-order, i.e., before their contents. Note, the default is not
   a breadth-first traversal.

GNU man 1 find:

 -depth Process each directory's contents before the directory itself. The -delete
        action also implies -depth.
Patrick
fonte
2
Sim, mas o find (1) do FreeBSD diz -delete: “… O processamento de profundidade pela primeira vez está implícito por esta opção.”, E o GNU find (1) diz: “… -delete implica -thth ,…”, portanto não deve será necessário adicionar -depthao comando.
G-Man Diz 'Reinstate Monica'
1
Na página de findmanual do GNU : "Para evitar confusão, as opções globais devem ser especificadas na linha de comando após a lista de pontos de partida, imediatamente antes do primeiro teste, opção posicional ou ação. Se você especificar uma opção global em outro local, a localização será emita uma mensagem de aviso explicando que isso pode ser confuso ". Agora, -deleteé uma "opção global" após ~o comando fornecido. Também notei que não faz diferença se você adiciona -depthou não. Diretórios não vazios ficar recuperados (mas isso é provavelmente porque eu uso -maxdepthtambém)
David Tonhofer