Come eliminare questa directory non cancellabile?


40

Ho decompresso un file tar corrotto e sono riuscito a finire con alcune directory che non posso eliminare, se provo a eliminarlo, sembra che non possa essere trovato, ma lsmostra che è presente, sia con bash che con Python ottengo comportamento simile, tranne che dopo aver provato a eliminarlo con rm -rf, si lslamenta che non riesce a trovarlo, quindi lo elenca (vedi sotto dopo rm -rf). Il findcomando mostra che il file è presente, ma non riesco ancora a pensare a un modo per eliminarlo.
Ecco i miei tentativi:

Qui vedi entrambi lse findaccetti che abbiamo una directory,

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

Ma non posso cancellarlo:

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

Posso cdfarlo ed è vuoto:

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


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

vedi sotto che non è un semplice file ma una directory, inoltre lssi comporta in modo divertente dopo rm -rf che dice che non riesce a trovare il file quindi lo elenca subito dopo:

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]$ 

Quindi questo è il tentativo con Python, il file viene trovato, ma il nome non è utilizzabile come nome che può essere eliminato:

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'

anche quando uso il completamento della scheda il nome che prende non è utilizzabile:

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

usando il nome che Python mostra con bash ottengo questo:

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

C'è qualcosa che posso fare per sbarazzarmi di questa dir corrotta? Il file system sottostante (NFS) sembra funzionale e non vengono segnalati altri problemi, e non ho avuto tali problemi fino al file tar corrotto.

EDIT: Qui sta usando findl' -execopzione propria di chiamarerm

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]$

ma il file è ancora lì, (si lslamenta che non lo trova, ma lo mostra comunque)

2a modifica:

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

Il comportamento è ancora invariato, il file è ancora presente

3a modifica:

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

Sembra che ci sia qualcosa di più nel nome che mikeaâcntguardare l'output del tentativo di Python mikea\xc3\xa2\xc2\x81\xc2\x84cnt, e questo screenshot:

È uscita

4 ° EDIT: questo è il tentativo con un jolly:

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 il mio locale:

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 modifica:

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

ma anche il comportamento è cambiato, ora lse cd fai questo:

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.

Questo è successo dopo i tentativi di eliminazione, sto pensando che potrebbero essere problemi di NFS come suggerito in una delle risposte qui da vinc17.

6 ° EDIT: questo è l'output di lsofels -a

rl] $ / usr / sbin / lsof mikeaâ ^ Á ^ Äcnt lsof: errore di stato su mikeaâ \ xc2 \ x81 \ xc2 \ x84cnt: nessun file o directory

sopra è sbagliato, ecco l' lsofinvocazione corretta : (rl è la directory principale)

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

7a modifica: lo spostamento non funzionerà (l'ho provato prima di tutto, ma non ho salvato l'output), ma ha lo stesso problema lse rm con il file.

8a EDIT: questo sta usando i caratteri esadecimali come suggerito:

 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]$

9a modifica: per il statcomando:

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

Sembra ancora più probabile da tutto l'output, c'è un bug o un altro comportamento scorretto di NFS come suggerito nei commenti.

Modifica 10: Questo è l'output di Strace in breve poiché è così grande, è l'output o questi due comandi:

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

https://gist.github.com/mikeatm/e07fa600747a4285e460

Modifica 11: Prima di quanto sopra rmdirho notato che potevo cdentrare nella directory, ma dopo rmdirnon ho potuto di cdnuovo, simile a ieri. I file .e ..erano presenti:

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

Modifica finale: ho visto un amministratore locale su questo ed è stato risolto accedendo al server stesso ed eliminando da lì. La spiegazione da loro è che potrebbe essere un problema con insiemi di caratteri nel nome inappropriati.


C'è un motivo per cui stai eseguendo findil piping dell'output a un comando diverso invece di utilizzare solo l' execopzione?
HalosGhost

@HalosGhost non c'era motivo, vedi modifica per ulteriori informazioni sulla tua domanda
mike-m

2
Come qualcuno con pochissima esperienza con unix e linux, ecco la mia idea: prova a rinominare la directory in qualcosa senza usare quei simboli mv. forse puoi eliminarlo dopo quello. In alternativa, puoi provare a spostare la directory su un livello di cartella più profondo (magari con un carattere jolly) e quindi eliminare la cartella in cui l'hai spostata.
Nzall,

4
Sospetto che la directory esista solo nella memoria del client e sia andata a lungo sul server. Hai provato a smontarlo e montarlo di nuovo? Hai provato a riavviare il client? È visibile su altri client?
Kasperd,

6
@ mike-m Sembra che tu abbia colpito un bug NFS, probabilmente nel server NFS. Quello o il danneggiamento del filesystem sul server. Dubito che tu possa davvero fare nient'altro che aspettare che gli amministratori del server NFS lo gestiscano.
derobert,

Risposte:


11

Il seguente estratto di questo saggio spiega potenzialmente perché quella directory si rifiuta di essere cancellata:

NFSv4 richiede che tutti i nomi dei file vengano scambiati tramite UTF-8 via cavo. La specifica NFSv4, RFC 3530, afferma che i nomi dei file dovrebbero essere codificati UTF-8 nella sezione 1.4.3: "In una leggera partenza, i nomi di file e directory sono codificati con UTF-8 per trattare le basi dell'internazionalizzazione". Lo stesso testo si trova anche nella più recente NFS 4.1 RFC (RFC 5661) sezione 1.7.3. L'attuale client Linux NFS passa semplicemente i nomi dei file direttamente, senza alcuna conversione dalle impostazioni internazionali correnti ae da UTF-8. L'uso di nomi di file non UTF-8 potrebbe essere un vero problema su un sistema che utilizza un sistema NFSv4 remoto; qualsiasi server NFS che segue le specifiche NFS dovrebbe rifiutare nomi di file non UTF-8. Quindi, se vuoi assicurarti che i tuoi file possano essere effettivamente archiviati da un client Linux a un server NFS, devi attualmente usare i nomi dei file UTF-8. In altre parole,

UTF-8 è un approccio a più lungo termine. I sistemi devono supportare UTF-8 e le molte codifiche precedenti, dando alle persone il tempo di passare a UTF-8. Per utilizzare "UTF-8 ovunque", tutti gli strumenti devono essere aggiornati per supportare UTF-8. Anni fa, questo era un grosso problema, ma a partire dal 2011 questo è essenzialmente un problema risolto, e penso che la traiettoria sia molto chiara per quei pochi sistemi finali.

Non tutte le sequenze di byte sono UTF-8 legali e non è necessario capire come visualizzarle. Se il kernel applica queste restrizioni, assicurando che siano consentiti solo i nomi di file UTF-8, allora non ci sono problemi ... tutti i nomi di file saranno UTF-8 legali. La funzione utf8_check C di Markus Kuhn può determinare rapidamente se una sequenza è UTF-8 valida.

Il filesystem dovrebbe richiedere che i nomi dei file soddisfino alcuni standard, non a causa di una cattiva necessità di controllare le persone, ma semplicemente in modo che i nomi possano sempre essere visualizzati correttamente in un secondo momento. La mancanza di standard rende le cose più difficili per gli utenti, non più facili. Tuttavia il filesystem non forza i nomi dei file in UTF-8, quindi può facilmente avere immondizia.


Questo sembra fare eco alla spiegazione degli amministratori locali, lo segnerò come la risposta della spiegazione degli amministratori. Guarda la mia modifica finale
mike-m

19

Un modo per eliminare file / directory come questo è tramite il riferimento all'inode.

Per trovare gli inode per gli elementi nella directory corrente:

ls -i
14813568 mikeaâcnt

Per eliminare questo:

find . -inum 14813568 -delete

si prega di vedere 5a modifica.
mike-m,

4
No, questo non cancella i file dal loro inode. Questo cerca un nome di file per l'inode specificato, quindi elimina il file con il suo nome. Qui non può essere d'aiuto, poiché è già stato effettuato un tentativo con il nome corretto (insieme ad altri tentativi con un nome errato).
Gilles 'SO- smetti di essere malvagio' il

@Gilles: tecnicamente cerca un inode odontoiatrico e restituisce un nome file, ma sono d'accordo.
Mikeserv,

1
@Nicolai non mi aiuta. Viene visualizzato il messaggio Directory non vuota.
diffracteD

1
Sì, hah, storia divertente su questo: il file che sto cercando di eliminare ha ?come riferimento inode. Come lo elimini allora?
Fondi Monica's Lawsuit,

7

Non dovresti usare caratteri non ASCII nella riga di comando poiché, come puoi vedere, per qualche ragione, non corrisponderanno necessariamente al nome del file (Unicode ha vari modi per esprimere lettere accentate). Qualcosa di simile a:

rm -rf mike*

dovrebbe funzionare poiché il nome file è generato direttamente dalla shell. Ma assicurati che ci sia una sola partita (fai una echo mike*prima per confermare).

Bene, se cdfunziona, allora non c'è motivo per cui rmo lsdebba dire No such file or directory, quindi il problema potrebbe essere a livello di file system.

Nota: non utilizzare lsper scoprire se una directory è vuota, ma ls -a.

La directory può ancora essere utilizzata da un altro processo (incluso se è il cwd di qualche processo). IMHO, ecco perché "esiste", ma può produrre errori, ad es. Con ls; lsofpotrebbe darti alcune informazioni, ma con NFS, devi trovare quale macchina lo utilizza. Soprattutto con NFS, questo può produrre strani errori. ls -anella directory principale potrebbe mostrare .nfs*file / directory in alcuni casi.

Quando avrai:

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

Sospetto che il file esista ancora nella tabella delle directory a causa della memorizzazione nella cache NFS e / o perché è utilizzato da un altro processo, ma senza informazioni associate. Quando lstenta di ottenere informazioni sul file stesso, viene visualizzato un errore in quanto il file stesso non esiste più (è solo nella tabella della directory), quindi l'errore visualizzato. Quindi lsgenera il nome del file perché si trova nella tabella della directory. Il fatto che tu abbia punti interrogativi in ​​un caso ma non nell'altro caso è dovuto a un bug di visualizzazione di lsIMHO (non correlato al tuo problema).


avevo provato un jolly in precedenza, non funzionava e non sono riuscito a pubblicare quel tentativo nella mia domanda, aggiornerò con il risultato
mike-m

Vedi la mia terza modifica. IMHO questo è dovuto a NFS (probabilmente non corruzione, ma cattiva memorizzazione nella cache) e probabilmente al fatto che un altro processo sta usando la directory. In alcuni casi, è necessario riavviare tutto (il server e i client).
vinc17,

Forse questo potrebbe spiegare le cose, ma non posso essere sicuro poiché non ho i privilegi di prenderlo per i test. Vedi la 5a modifica.
mike-m,

1
@ vinc17 Per favore non usare "EDIT" nella tua risposta, perché per i nuovi lettori non ha senso (c'è già una cronologia delle modifiche)
Bernhard

iv ha aggiunto un po 'di output lsof, non sono sicuro che possa dirti qualcosa,
mike-m

3

Ho testato personalmente usando findla -execdirettiva:

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

La cartella è stata creata e rimossa correttamente.

Come sottolineato da @Igeorget , c'è un metodo ancora più semplice se hai GNU find:

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

Ho anche testato questo comando e funziona correttamente


E se usi GNU's find, c'è -deleteanche un'opzione.
lgeorget,

Vedi la terza modifica,
mike-m

1

Ho avuto lo stesso problema, credo. Ho visto il problema in precedenza con un nome file di . lsin questo caso â??ho visualizzato il file come , ma sono stato in grado di eliminarlo con rm ☃.

Questo mi ha portato al seguente modo per convertire il nome sbagliato in quello corretto:

Prima ottenere i byte del nome file:

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

Quindi decodifica questi byte come UTF-8, per ottenere i punti di codice unicode, utilizzando l'input esadecimale di questo sito Web, ad esempio: 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

Si noti che sono tutti al di sotto del limite di byte. Otteniamo i seguenti byte:

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

Se trattiamo questa sequenza su UTF-8 otteniamo:

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 quindi il tuo nome file è:, mikea⁄cntcon una barra di frazione anziché una normale in avanti. Ora puoi passare questo nome a rmdir.


È geniale, se lo incontro di nuovo, lo terrò a mente. buona. +1
mike-m,

0

Dopo aver ottenuto il codice esadecimale corretto del nome di file / cartella (usando qualunque metodo ritenga opportuno, potrei scegliere ls --show-control-chars | xxd), si dovrebbe usare un costrutto speciale per indirizzare tali caratteri quando si esegue sotto bash:

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

Altrimenti le barre rovesciate vengono trattate come barre rovesciate alla vaniglia.


Dai un'occhiata alla mia modifica (8a modifica)
mike-m

@ mike-m Ovviamente non esiste, perché lsinclude newline nei dati di output e il "cnt" è duplicato. Forse puoi provare direttamente a copiare e incollare la riga nella mia risposta e vedere se è efficace?
Abel Cheung,

No, ancora questo: `` rl] $ rmdir $ 'mikea \ xc3 \ xa2 \ xc2 \ x81 \ xc2 \ x84cnt' rmdir: impossibile rimuovere `mikeaâ \ 302 \ 201 \ 302 \ 204cnt ': nessun file o directory ``
mike-m

In tal caso è molto probabile una combinazione del problema NFS e delle impostazioni internazionali che impediscono alla maggior parte delle utility di sistema di passare byte non UTF8 errati. E sembra che la rimozione dell'inode abbia peggiorato la situazione. Per ora, l'unico modo a cui riesco a pensare è impostare il tuo sistema su un ambiente privo di impostazioni locali (usa le impostazioni locali "C" per LC_*e le LANGvariabili env) e montare NFS senza opzioni di set di caratteri
Abel Cheung,

0

Hai provato a utilizzare rm -rf ./mikeaâcnto rm -rf "./mikeaâcnt"o un percorso assoluto? Inoltre, invece di rmprovare rmdir ./mikeaâcnt.


parte del problema è che i personaggi mikeaâcntsembrano non essere il nome del file, ma ciò che ls viene visualizzato, vedere la terza modifica
mike-m

0

Hai provato a ottenere l'inode di quel file con stat:

stat mike*

Questo dovrebbe darti il ​​numero di inode (e altri dati), e quindi potresti provare a cancellarlo.


iv ha aggiunto una modifica con statbehavour,
mike-m

0

Ho avuto problemi simili. Hai Gnome, KDE o una specie di Xwindow DM ?. Se si apre il file broser e si rimuove il file da lì.

Dovrebbe funzionare.

Vorrei vedere una soluzione dalla riga di comando, ma nel mio caso e dopo aver perso molto tempo a cercare di capire come rimuoverla dalla riga di comando ho scoperto che era semplice come rimuovere qualsiasi altro file da nautilus o qualsiasi altro esploratore di file (la verità è che ho provato solo con nautilus).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.