desenv-web-rp.com

Como excluir este diretório indelével?

Descompactei um arquivo tar corrompido e consegui terminar com um diretório que não consigo excluir. Se tentar excluí-lo, parece que ele não pode ser encontrado, mas ls mostra que está presente, ambos com bash e com python recebo comportamento semelhante, exceto logo após tentar excluí-lo com rm -rf, ls reclama que não conseguiu encontrá-lo e o lista (veja abaixo depois de rm -rf). O comando find mostra que o arquivo está presente, mas ainda não consigo pensar em uma maneira de excluí-lo.
Aqui estão minhas tentativas:

Aqui você vê ls e find concordam que temos um diretório,

rl]$ ls
mikeaâ??cnt
rl]$ find -maxdepth 1 -type d -empty -print0  
./mikeaâcnt 

Mas não posso excluí-lo:

rl]$ find -maxdepth 1 -type d -empty -print0 |  xargs -0 rm -f -v 
rm: cannot remove `./mikeaâ\302\201\302\204cnt': Is a directory
rl]$ ls
mikeaâ??cnt

Mas eu posso cd e está vazio:

rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ pwd
.../rl/mikeaâcnt


mikeaâ^Á^Äcnt]$ cd ../
rl]$ ls
mikeaâ??cnt

veja abaixo que não é um arquivo simples, mas um diretório, mais ls se comporta de maneira engraçada após o rm -rf ele diz que não consegue encontrar o arquivo e o lista imediatamente depois:

rl]$ rm mikeaâ^Á^Äcnt/
rm: cannot remove `mikeaâ\302\201\302\204cnt/': Is a directory
rl]$ rm -rf  mikeaâ^Á^Äcnt/
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$ 

Portanto, esta é a tentativa com python, o arquivo foi encontrado, mas o nome não pode ser usado como um nome que pode ser excluído:

rl]$ python 
Python 2.6.6 (r266:84292, Jul 10 2013, 22:48:45) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import shutil
>>> os.listdir('.')
['mikea\xc3\xa2\xc2\x81\xc2\x84cnt']
>>> shutil.rmtree(os.listdir('.')[0] )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/shutil.py", line 204, in rmtree
    onerror(os.listdir, path, sys.exc_info())
  File "/usr/lib64/python2.6/shutil.py", line 202, in rmtree
    names = os.listdir(path)
OSError: [Errno 2] No such file or directory: 'mikea\xc3\xa2\xc2\x81\xc2\x84cnt'

mesmo quando uso o preenchimento da guia, o nome escolhido não é utilizável:

rl]$ rm -rf mikeaâ^Á^Äcnt 
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

usando o nome que python mostra com bash eu recebo isso:

rl]$ rm -rf "mikea\xc3\xa2\xc2\x81\xc2\x84cnt"
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

Existe algo que eu possa fazer para me livrar desse diretório corrompido? O sistema de arquivos subjacente (NFS) parece funcional e nenhum outro problema foi relatado, e eu não tive esses problemas até o arquivo tar corrompido.

EDIT: Aqui está usando o próprio find-exec opção para chamar rm

rl]$ find -maxdepth 1 -type d -empty -exec rm -f {} \;
find: `./mikeaâ\302\201\302\204cnt': No such file or directory
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$

mas o arquivo ainda está lá (ls reclama que não foi encontrado, mas mostra mesmo assim)

2ª EDIÇÃO:

rl]$ find -maxdepth 1 -type d -empty -exec rm -rf {} \;
find: `./mikeaâ\302\201\302\204cnt': No such file or directory
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

O comportamento ainda é inalterado, o arquivo ainda está presente

3ª EDIÇÃO:

rl]$ ls
mikeaâ??cnt
rl]$ find -maxdepth 1 -type d -empty -exec rm -rf {} + 
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

Parece haver mais no nome do que mikeaâcnt olhando para a saída da python tentativa mikea\xc3\xa2\xc2\x81\xc2\x84cnt e esta captura de tela:

ls output

4ª EDIÇÃO: Esta é a tentativa com um curinga:

rl]$ echo * 
mikeaâcnt
rl]$ echo mike* 
mikeaâcnt
rl]$ rm -rf mike*
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

e meu local:

rl]$  locale
LANG=en_US.utf8
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=

5a Edição:

rl]$ ls -i 
ls: cannot access mikeaâcnt: No such file or directory
? mikeaâ??cnt

mas também o comportamento mudou, agora ls e cd fazem o seguinte:

rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$ cd mikeaâ^Á^Äcnt 
mikeaâcnt: No such file or directory.

Isso aconteceu após as tentativas de exclusão. Estou pensando que podem ser problemas do NFS, conforme sugerido em uma das respostas aqui por vinc17.

6ª EDIÇÃO: Esta é a saída de lsof e ls -a

rl] $/usr/sbin/lsof mikeaâ € ïcnt lsof: erro de status no mikeaâ\xc2\x81\xc2\x84cnt: esse arquivo ou diretório não existe

acima está errado, aqui está a chamada lsof correta: (rl é o diretório pai)

rl]$ /usr/sbin/lsof | grep mike | grep rl 
tcsh      11926   mike  cwd       DIR   0,33     4096 19569249 /home/mike/mish/rl
lsof      14733   mike  cwd       DIR   0,33     4096 19569249 /home/mike/mish/rl
grep      14734   mike  cwd       DIR   0,33     4096 19569249 /home/mike/mish/rl
grep      14735   mike  cwd       DIR   0,33     4096 19569249 /home/mike/mish/rl
lsof      14736   mike  cwd       DIR   0,33     4096 19569249 /home/mike/mish/rl
rl]$ 

rl]$ ls -a
ls: cannot access mikeaâcnt: No such file or directory
.  ..  mikeaâ??cnt

7ª Edição: o movimento não funcionará (tentei antes de tudo isso, mas não salvei a saída), mas ele tem o mesmo problema que ls e rm com o arquivo.

8ª EDIÇÃO: use os caracteres hexadecimais, conforme sugerido:

 rl]$ ls --show-control-chars | xxd
0000000: 6d69 6b65 61c3 a2c2 81c2 8463 6e74 0a    mikea......cnt.
rl]$ rmdir $'mikea\6d69\6b65\61c3\a2c2\81c2\8463\6e74\0acnt' 
rmdir: failed to remove `mikea\006d69\006b651c3\a2c2\\81c2\\8463\006e74': No such file or directory
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$

9ª Edição: para o comando stat:

 rl]$ stat  mikeaâ^Á^Äcnt 
stat: cannot stat `mikeaâ\302\201\302\204cnt': No such file or directory
 rl]$

Parece ainda mais provável de toda a saída, há um bug ou outro mau comportamento do NFS, conforme sugerido nos comentários.

Edit 10: Esta é uma saída strace em um Gist, pois é tão grande, é a saída ou estes dois comandos:

strace -xx rmdir ./* | grep -e '-1 E'`
strace -xx -e trace=file ls -li`

https://Gist.github.com/mikeatm/e07fa600747a4285e46

Edit 11: Então, antes do rmdir acima, notei que eu poderia cd no diretório, mas após o rmdir não pude cd novamente, semelhante a ontem. O . e .. arquivos estavam presentes:

rl]$ ls
mikeaâ??cnt
rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ ls  -a
.  ..
mikeaâ^Á^Äcnt]$ cd ../

Edição final: vi um administrador local sobre isso e foi resolvido fazendo logon no próprio servidor e excluindo a partir daí. A explicação deles é que pode ser um problema com conjuntos de caracteres no nome sendo inapropriados.

40
mike-m

O seguinte trecho de este ensaio potencialmente explica por que esse diretório se recusa a ser excluído:

O NFSv4 exige que todos os nomes de arquivos sejam trocados usando UTF-8 pela conexão. A especificação NFSv4, RFC 3530, diz que os nomes de arquivos devem ser codificados em UTF-8 na seção 1.4.3: “Em uma partida ligeira, os nomes de arquivos e diretórios são codificados em UTF-8 para lidar com o básico da internacionalização”. O mesmo texto também é encontrado na seção 1.7.3 da NFS 4.1 RFC (RFC 5661) mais recente. O atual cliente NFS do Linux simplesmente passa os nomes dos arquivos diretamente, sem nenhuma conversão do código do idioma atual para e do UTF-8. Usar nomes de arquivos que não sejam UTF-8 pode ser um problema real em um sistema que usa um sistema NFSv4 remoto; qualquer servidor NFS que siga a especificação NFS deve rejeitar nomes de arquivos que não sejam UTF-8. Portanto, se você deseja garantir que seus arquivos possam realmente ser armazenados de um cliente Linux para um servidor NFS, você deve atualmente usar nomes de arquivos UTF-8. Em outras palavras, embora algumas pessoas pensem que o Linux não força uma codificação de caractere específica nos nomes de arquivos, na prática ele já requer codificação UTF-8 para nomes de arquivos em certos casos.

UTF-8 é uma abordagem de longo prazo. Os sistemas precisam suportar UTF-8, bem como muitas codificações mais antigas, dando às pessoas tempo para mudar para UTF-8. Para usar “UTF-8 em qualquer lugar”, todas as ferramentas precisam ser atualizadas para oferecer suporte ao UTF-8. Anos atrás, esse era um grande problema, mas a partir de 2011 esse é essencialmente um problema resolvido, e acho que a trajetória é muito clara para esses poucos sistemas de rastreamento.

Nem todas as sequências de bytes são UTF-8 legais e você não precisa descobrir como exibi-las. Se o kernel aplicar essas restrições, garantindo que apenas nomes de arquivos UTF-8 sejam permitidos, não há problema ... todos os nomes de arquivos serão UTF-8 legais. A função utf8_check C de Markus Kuhn pode determinar rapidamente se uma sequência é UTF-8 válida.

O sistema de arquivos deve exigir que os nomes de arquivos atendam a algum padrão, não por causa de alguma necessidade maligna de controlar as pessoas, mas simplesmente para que os nomes sempre possam ser exibidos corretamente posteriormente. A falta de padrões torna as coisas mais difíceis para os usuários, não mais fáceis. No entanto, o sistema de arquivos não força os nomes de arquivos a serem UTF-8, para que possa ter lixo facilmente.

11
Timothy Martin

Uma maneira de excluir arquivos/diretórios como esse é pela referência de inode.

Para encontrar os inodes para elementos no diretório atual:

ls -i
14813568 mikeaâcnt

Para excluir isso:

find . -inum 14813568 -delete
19
Nicolai

Você não deve usar caracteres não ASCII na linha de comando, pois, como você pode ver, por algum motivo, eles não corresponderão necessariamente ao nome do arquivo (o Unicode possui várias maneiras de expressar letras acentuadas). Algo como:

rm -rf mike*

deve funcionar, pois o nome do arquivo é gerado diretamente pelo Shell. Mas verifique se há apenas uma correspondência (faça uma echo mike* primeiro a confirmar).

Bem, se cd funciona, não há razão para que rm ou ls digam No such file or directory, para que o problema possa estar no nível do sistema de arquivos.

Nota: Não use ls para descobrir se um diretório está vazio, mas ls -a.

O diretório ainda pode ser usado por outro processo (incluindo se é o cwd de algum processo). IMHO, é por isso que ainda "existe", mas pode gerar erros, por exemplo com ls; lsof pode fornecer algumas informações, mas com o NFS, você precisa descobrir qual máquina a utiliza. Especialmente com o NFS, isso pode gerar erros estranhos. ls -a no diretório pai pode mostrar a você .nfs* arquivos/diretórios em alguns casos.

Quando você obtém:

$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

Suspeito que o arquivo ainda exista no tabela de diretórios devido ao cache do NFS e/ou porque é usado por outro processo, mas sem informações associadas. Quando ls tenta obter informações sobre o próprio arquivo, ele recebe um erro, já que o arquivo em si não existe mais (está apenas na tabela de diretórios), daí o erro exibido. Então ls gera o nome do arquivo porque ele está na tabela de diretórios. O fato de você ter pontos de interrogação em um caso, mas não no outro, deve-se a um erro de exibição de ls IMHO (não relacionado ao seu problema).

7
vinc17

Eu pessoalmente testei usando find 's -exec diretiva:

$ mkdir -p mikeaâcnt
$ ls
mikeaâcnt
$ find -maxdepth 1 -type d -empty -exec rm -rf {} +
$ ls
$ 

A pasta foi criada e removida corretamente.

Como apontado por @ Igeorget , existe um método ainda mais simples se você tiver GNU find:

$ find -maxdepth 1 -type d -empty -delete

Eu também testei este comando, e ele funciona corretamente

3
HalosGhost

Eu tive o mesmo problema, acredito. Eu já vi o problema anteriormente com um nome de arquivo . ls neste caso, exibiu o arquivo como â??, mas consegui excluí-lo com rm ☃.

Isso me levou à seguinte maneira de converter o nome errado para o correto:

Primeiro obtenha os bytes do nome do arquivo:

$ ls --show-control-chars | xxd
0000000: 6d69 6b65 61c3 a2c2 81c2 8463 6e74 0a    mikea......cnt.

Em seguida, decodifique esses bytes como UTF-8, para obter os pontos de código unicode, usando a entrada hexadecimal deste site, por exemplo: http://software.hixie.ch/utilities/cgi/unicode-decoder/utf8-decoder

U+006D LATIN SMALL LETTER M character
U+0069 LATIN SMALL LETTER I character
U+006B LATIN SMALL LETTER K character
U+0065 LATIN SMALL LETTER E character
U+0061 LATIN SMALL LETTER A character
U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX character (&#x00E2;)
U+0081 <control> character (&#x0081;)
U+0084 <control> character (&#x0084;)
U+0063 LATIN SMALL LETTER C character
U+006E LATIN SMALL LETTER N character
U+0074 LATIN SMALL LETTER T character

Observe que todos estão abaixo do limite de bytes. Obtemos os seguintes bytes:

6D 69 6B 65 61 E2 81 84 63 6E 74

Se tratarmos essa sequência no UTF-8, obtemos:

U+006D LATIN SMALL LETTER M character
U+0069 LATIN SMALL LETTER I character
U+006B LATIN SMALL LETTER K character
U+0065 LATIN SMALL LETTER E character
U+0061 LATIN SMALL LETTER A character
U+2044 FRACTION SLASH character (&#x2044;)
U+0063 LATIN SMALL LETTER C character
U+006E LATIN SMALL LETTER N character
U+0074 LATIN SMALL LETTER T character

E, portanto, seu nome de arquivo é: mikea⁄cnt, com uma barra de fração em vez de uma barra de avanço normal. Agora você pode passar esse nome para rmdir.

1
mvdnes

Você já tentou usar rm -rf ./mikeaâcnt ou rm -rf "./mikeaâcnt" ou um caminho absoluto? Além disso, em vez de rm, tente rmdir ./mikeaâcnt.

0
walsht

Você tentou obter o inode desse arquivo com stat:

stat mike*

Isso deve fornecer o número do inode (e outros dados) e, em seguida, você pode tentar excluí-lo.

0
rsuarez

Eu tive problemas semelhantes. Você tem Gnome, KDE ou algum tipo de Xwindow DM ?. Se você abrir o arquivo broser e remover o arquivo de lá.

Deveria funcionar.

Gostaria de ver uma solução na linha de comando, mas, no meu caso, e depois de perder muito tempo tentando descobrir como removê-la da linha de comando, achei que era tão simples quanto remover qualquer outro arquivo do nautilus ou qualquer outro explorador de arquivos (a verdade é que só tentei com o nautilus).

0
YoMismo

Depois de obter o código hexadecimal correto do nome do arquivo/pasta (usando o método que achar melhor, posso escolher ls --show-control-chars | xxd), alguma construção especial deve ser usada para endereçar esses caracteres ao executar no bash:

rmdir $'mikea\xc3\xa2\xc2\x81\xc2\x84cnt'

Caso contrário, as barras invertidas são tratadas como barra invertida de baunilha.

0
Abel Cheung