Como apagar este diretório undeletable?

40

Eu descompactei um arquivo tar corrompido e consegui terminar com algum diretório que eu não consigo apagar, Se eu tentar excluí-lo, parece que não pode ser encontrado, mas ls mostra que está presente, tanto com o bash quanto com o python Eu tenho um comportamento semelhante, exceto logo depois de tentar excluí-lo com rm -rf , ls reclama que não consegue encontrá-lo, então ele o lista (veja abaixo após 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ê os dois 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 consigo excluir:

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

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 engraçado depois que rm -rf diz que não pode encontrar o arquivo, em seguida, o relaciona logo em seguida:

rl]$ rm mikeaâ^Á^Äcnt/
rm: cannot remove 'mikeaâ2124cnt/': 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 é encontrado, mas o nome não é utilizável 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 eu uso o término da tabulação, o nome que ele pega 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 corrupto? O sistema de arquivos subjacente (NFS) parece funcional e nenhum outro problema é relatado, e eu não tive tais problemas até o arquivo tar corrompido.

EDITAR: Aqui está usando a própria opção find do -exec para chamar rm

rl]$ find -maxdepth 1 -type d -empty -exec rm -f {} \;
find: './mikeaâ2124cnt': 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 pode encontrá-lo, mas mostra de qualquer maneira)

2º EDIT:

rl]$ find -maxdepth 1 -type d -empty -exec rm -rf {} \;
find: './mikeaâ2124cnt': 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

EDIT:

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 que mikeaâcnt de ver a saída da tentativa de python mikea\xc3\xa2\xc2\x81\xc2\x84cnt e esta captura de tela:

4ºEDIT:Estaéatentativacomumcuringa:

rl]$echo*mikeaâcntrl]$echomike*mikeaâcntrl]$rm-rfmike*rl]$lsls:cannotaccessmikeaâcnt:Nosuchfileordirectorymikeaâ??cnt

eminhalocalidade:

rl]$localeLANG=en_US.utf8LC_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=

5ª 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 isso:

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 depois das tentativas de exclusão, estou pensando que podem ser problemas de NFS, como sugerido em uma das respostas aqui por vinc17.

6º EDIT: Esta é a saída de lsof e ls -a

    rl] $ / usr / sbin / lsof mikeaâ ^ Äcnt     lsof: status error no mikeaâ \ xc2 \ x81 \ xc2 \ x84cnt: Nenhum arquivo ou diretório   

acima está errado, aqui está a invocação correta de lsof : (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: move não funciona, (tentei antes de tudo isso, mas não salvei a saída), mas tem o mesmo problema que ls e rm com o arquivo.

8ª EDIÇÃO: isto está usando os caracteres hexadecimais como sugerido:

 rl]$ ls --show-control-chars | xxd
0000000: 6d69 6b65 61c3 a2c2 81c2 8463 6e74 0a    mikea......cnt.
rl]$ rmdir $'mikead69b65c3\a2c2c263e74
 rl]$ stat  mikeaâ^Á^Äcnt 
stat: cannot stat 'mikeaâ2124cnt': No such file or directory
 rl]$
acnt' rmdir: failed to remove 'mikea
strace -xx rmdir ./* | grep -e '-1 E''
strace -xx -e trace=file ls -li'
6d69
rl]$ ls
mikeaâ??cnt
rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ ls  -a
.  ..
mikeaâ^Á^Äcnt]$ cd ../
6b651c3\a2c2\81c2\8463
rl]$ ls
mikeaâ??cnt
rl]$ find -maxdepth 1 -type d -empty -print0  
./mikeaâcnt 
6e74': 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]$ find -maxdepth 1 -type d -empty -print0 |  xargs -0 rm -f -v 
rm: cannot remove './mikeaâ2124cnt': Is a directory
rl]$ ls
mikeaâ??cnt

Parece ainda mais provável de todos os resultados, há um bug ou outro mau comportamento do NFS como sugerido nos comentários.

Editar 10: Esta é a saída strace em uma essência desde que é tão grande, é a saída ou esses dois comandos:

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


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

link

Editar 11: Então, antes do rmdir acima, percebi que eu poderia cd no diretório, mas depois do rmdir eu não consegui cd novamente, semelhante ao ontem. Os arquivos . e .. estavam presentes:

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

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

    
por mike-m 30.07.2014 / 10:53

9 respostas

11

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

NFSv4 requires that all filenames be exchanged using UTF-8 over the wire. The NFSv4 specification, RFC 3530, says that filenames should be UTF-8 encoded in section 1.4.3: “In a slight departure, file and directory names are encoded with UTF-8 to deal with the basics of internationalization.” The same text is also found in the newer NFS 4.1 RFC (RFC 5661) section 1.7.3. The current Linux NFS client simply passes filenames straight through, without any conversion from the current locale to and from UTF-8. Using non-UTF-8 filenames could be a real problem on a system using a remote NFSv4 system; any NFS server that follows the NFS specification is supposed to reject non-UTF-8 filenames. So if you want to ensure that your files can actually be stored from a Linux client to an NFS server, you must currently use UTF-8 filenames. In other words, although some people think that Linux doesn’t force a particular character encoding on filenames, in practice it already requires UTF-8 encoding for filenames in certain cases.

UTF-8 is a longer-term approach. Systems have to support UTF-8 as well as the many older encodings, giving people time to switch to UTF-8. To use “UTF-8 everywhere”, all tools need to be updated to support UTF-8. Years ago, this was a big problem, but as of 2011 this is essentially a solved problem, and I think the trajectory is very clear for those few trailing systems.

Not all byte sequences are legal UTF-8, and you don’t want to have to figure out how to display them. If the kernel enforces these restrictions, ensuring that only UTF-8 filenames are allowed, then there’s no problem... all the filenames will be legal UTF-8. Markus Kuhn’s utf8_check C function can quickly determine if a sequence is valid UTF-8.

The filesystem should be requiring that filenames meet some standard, not because of some evil need to control people, but simply so that the names can always be displayed correctly at a later time. The lack of standards makes things harder for users, not easier. Yet the filesystem doesn’t force filenames to be UTF-8, so it can easily have garbage.

    
por 31.07.2014 / 02:24
19

Uma maneira de excluir arquivos / direcórios como este é por sua inode-reference.

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

ls -i
14813568 mikeaâcnt

Para excluir isso:

find . -inum 14813568 -delete
    
por 30.07.2014 / 11:45
7

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 formas de expressar letras acentuadas). Algo como:

rm -rf mike*

deve funcionar, pois o nome do arquivo é gerado diretamente pelo shell. Mas certifique-se de que há apenas uma correspondência (faça um echo mike* primeiro para confirmar).

Bem, se cd funcionar, não há motivo para que rm ou ls diga No such file or directory , para que o problema esteja 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 for o cwd de algum processo). IMHO, é por isso que ainda "existe", mas pode gerar erros, por ex. com ls ; lsof pode lhe dar algumas informações, mas com o NFS, você precisa descobrir qual máquina o utiliza. Especialmente com o NFS, isso pode gerar erros estranhos. ls -a no diretório pai pode mostrar .nfs* files / directories em alguns casos.

Quando você começa:

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

Suspeito que o arquivo ainda exista na tabela de diretórios devido ao armazenamento em 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, pois o próprio arquivo não existe mais (é apenas na tabela de diretórios), portanto, o erro exibido. Então ls gera o nome do arquivo porque está na tabela de diretórios. O fato de você ter pontos de interrogação em um caso, mas não no outro caso, é devido a um erro de exibição de ls IMHO (não relacionado ao seu problema).

    
por 30.07.2014 / 11:21
3

Eu testei pessoalmente usando a diretiva find do -exec :

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

A pasta foi criada corretamente e removida corretamente.

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

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

Eu também testei este comando e ele funciona corretamente

    
por 30.07.2014 / 11:10
1

Eu tive o mesmo problema, acredito. Eu vi o problema anteriormente com um nome de arquivo de . ls neste caso exibiu o arquivo como â?? , mas eu 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: link

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 esta sequência em 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, o nome do arquivo é: mikea⁄cnt , com uma barra de fração em vez de um encaminhamento normal. Você pode agora passar este nome para rmdir .

    
por 16.09.2015 / 09:49
0

Depois de obter o código hexadecimal correto do nome do arquivo / pasta (usando qualquer método que seja adequado, eu posso escolher ls --show-control-chars | xxd ), alguma construção especial deve ser usada para endereçar tais caracteres quando rodando sob o bash:

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

Caso contrário, as barras invertidas são tratadas como barras invertidas.

    
por 30.07.2014 / 15:16
0

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 .

    
por 30.07.2014 / 18:20
0

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.

    
por 30.07.2014 / 18:56
0

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

Deve funcionar.

Eu gostaria de ver uma solução a partir da linha de comando, mas no meu caso e depois de perder muito tempo tentando descobrir como removê-lo da linha de comando, descobri que era tão simples quanto remover qualquer outro arquivo do nautilus ou qualquer outro explorador de arquivos (a verdade é que eu apenas tentei com o nautilus).

    
por 31.07.2014 / 09:51