Bu silinemez dizini nasıl silebilirim?


40

Bir bozuk tar dosyasını asfaltlanmaış ve bunu silmeye çalışırsanız ben silemezsiniz bazı dizinde ile bitirmek başardı, bu bulunamaz gibi görünüyor, ama lsgösterileri bash ile ve ben olsun piton ile hem 's hediye, benzer davranış, onu silmeye çalıştıktan hemen sonra rm -rf, lsbulamadığından şikayet eder, sonra listeler (sonradan aşağıya bakın rm -rf). findKomut gösterileri dosya mevcut olduğunu, ancak yine de bunu silmek için bir yol düşünemiyorum.
İşte girişimlerim:

Burada ikisini de görüyorsunuz lsve bir findrehberimiz olduğuna katılıyoruz,

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

Ancak silemiyorum:

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

cdYine de yapabilirim ve boş:

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


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

aşağıya bakın basit bir dosya değil, bir dizin, artı dosyayı bulamadığı lssöylendikten sonra komik davranır , rm -rfsonra da hemen sonra listeler:

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

Yani bu python girişimidir, dosya bulunur, ancak isim silinebilecek bir isim olarak kullanılamaz:

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'

sekme tamamlama kullandığımda bile, seçtiği isim kullanılamaz:

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

python'un bash ile gösterdiği ismi kullanarak şunu alıyorum:

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

Bu bozuk direkten kurtulmak için yapabileceğim bir şey var mı? Temel dosya sistemi (NFS) işlevsel görünüyor ve başka bir sorun bildirilmedi ve bozuk tar dosyasına kadar böyle bir sorun yaşamadım.

EDIT: İşte aramak için findkendi -execseçeneğini kullanıyorrm

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

ancak dosya hala orada, ( lsbulamıyor ancak şikayet ederse yine de gösteriyor)

2. EDIT:

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

Davranış hala değişmedi, dosya hala mevcut

3. 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

Adı mikeaâcnt, python girişiminin çıktısına bakmaktan daha çok görünüyor mikea\xc3\xa2\xc2\x81\xc2\x84cntve bu ekran görüntüsü:

ls çıktısı

4. EDIT: Bu bir joker kartla yapılan denemedir:

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

ve yerel ayarım:

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=

5. Düzenleme:

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

ama aynı zamanda davranış değişti, şimdi lsve cd bunu yapın:

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.

Bu silmek denemeden sonra oldu, ben cevaplar birinde söylediği gibi NFS sorunları olabileceğini düşünüyorum burada vinc17 tarafından.

6 DÜZENLEME: Bu çıkışı olan lsofvels -a

rl] $ / usr / sbin / lsof mikeaa ^ Á ^ Äcnt lsof: mikea'da durum hatası \ xc2 \ x81 \ xc2 \ x84cnt: Böyle bir dosya veya dizin yok

yukarıdaki yanlış, işte doğru lsofçağrı: (rl üst dizindir)

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 Düzenleme: hareket değil iş, (bütün bu daha önce denedim ama çıktı tasarruf etmedi), ancak aynı sorun lsve rm dosya ile.

8. EDIT: önerilen altıgen karakterleri kullanıyor:

 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. Düzenleme: statkomut için:

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

Tüm çıktılardan daha da muhtemel görünüyor, yorumlarda önerildiği gibi bir hata veya başka bir NFS hatalı davranışı var.

Düzenleme 10: Bu çok büyük, çıktısı veya bu iki komuttan dolayı, büyük bir çıkarımdadır:

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

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

Düzenleme 11: Öyleyse yukarıdakilerden önce dizine rmdirgirebildiğimi fark ettim cd, ancak ondan sonra tekrar dün rmdirolamayacağım cd. .Ve .. dosyalar mevcuttu:

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

Son Düzenleme: Bunun üzerinde yerel bir yönetici gördüm ve sunucuya giriş yaparak ve oradan silerek ilgilenildi. Onlardan açıklama, ismin karakter kümeleriyle uygunsuz olmasının bir sorun olabileceğidir.


findSadece execseçeneğini kullanmak yerine, çıktısını farklı bir komuta aktarmanızın bir nedeni var mı ?
HalosGhost

@HalosGhost bir sebep yoktu, sorunuza eklenmiş bilgi için düzenlemeye bakınız
mike-m

2
Unix ve linux konusunda çok az deneyime sahip biri olarak, benim fikrim: dizini bu sembolleri kullanmadan bir şeyle yeniden adlandırmayı deneyin mv. belki ondan sonra silebilirsin. Alternatif olarak, dizini daha derin bir klasör seviyesine taşımayı deneyebilirsiniz (belki bir joker karakter ile) ve sonra üzerine taşıdığınız klasörü silmeyi deneyebilirsiniz.
Nzall

4
Dizinin yalnızca istemcide bellekte bulunduğundan ve sunucuda uzun süre bulunduğundan şüpheleniyorum. Takmayı ve tekrar takmayı denediniz mi? Müşteriyi yeniden başlatmayı denedin mi? Diğer istemcilerde görünür mü?
kasperd

6
@ mike-m Muhtemelen NFS sunucusundaki bir NFS böceğine çarpmış gibisiniz. Ya bu ya da sunucudaki dosya sistemi bozulması. NFS sunucusu yöneticilerinin bununla uğraşmasını beklemekten başka bir şey yapabileceğinizi sanmıyorum.
derobert

Yanıtlar:


11

Bu makaleden çıkan alıntı, bu dizinin neden silinmeyi reddettiğini açıklar:

NFSv4, tüm dosya adlarının tel üzerinden UTF-8 kullanılarak değiştirilmesini gerektirir. NFSv4 spesifikasyonu, RFC 3530, dosya adlarının Bölüm 1.4.3'te UTF-8 olarak kodlanması gerektiğini söyledi: “Hafif bir ayrılma durumunda, dosya ve dizin adlarının uluslararasılaştırmanın temelleri ile başa çıkmak için UTF-8 ile kodlandığı”. ayrıca yeni NFS 4.1 RFC (RFC 5661) bölüm 1.7.3'te de bulunur. Mevcut Linux NFS istemcisi, dosya isimlerini doğrudan yerelden UTF-8'e ve oradan yerel bir çevreden dönüştürme olmadan geçirir. UTF-8 olmayan dosya adlarını kullanmak, uzak bir NFSv4 sistemi kullanan bir sistemde gerçek bir sorun olabilir; NFS belirtimini izleyen herhangi bir NFS sunucusunun UTF-8 olmayan dosya adlarını reddetmesi beklenir. Bu nedenle, dosyalarınızın gerçekten bir Linux istemcisinden NFS sunucusuna depolanabilmesini sağlamak istiyorsanız, şu anda UTF-8 dosya adlarını kullanmanız gerekir. Başka bir deyişle,

UTF-8 daha uzun vadeli bir yaklaşımdır. Sistemler UTF-8'in yanı sıra birçok eski kodlamayı da desteklemeli ve bu sayede insanlara UTF-8'e geçmeleri için zaman vermelidir. “Her yerde UTF-8'i kullanmak için, UTF-8'i desteklemek için tüm araçların güncellenmesi gerekir. Yıllar önce, bu büyük bir problemdi, ancak 2011 itibariyle bu aslında çözülmüş bir problemdi ve yörüngenin bu az sayıdaki takip sistemi için çok net olduğunu düşünüyorum.

Tüm bayt dizileri yasal UTF-8 değildir ve bunların nasıl gösterileceğini anlamak zorunda kalmazsınız. Çekirdek bu kısıtlamaları uygularsa, yalnızca UTF-8 dosya adlarına izin verildiğinden emin olmak durumunda, sorun olmaz ... tüm dosya adları yasal UTF-8 olacaktır. Markus Kuhn'ın utf8_check C işlevi bir dizinin UTF-8 geçerli olup olmadığını hızlı bir şekilde belirleyebilir.

Dosya sistemi, dosya adlarının, bazı insanları kontrol etme ihtiyacından dolayı değil, yalnızca adların daha sonra her zaman doğru bir şekilde görüntülenebilmesi için bazı standartlara uymasını gerektiriyor olmalıdır. Standartların olmaması, işleri kullanıcılar için zorlaştırır, kolaylaştırmaz. Ancak dosya sistemi dosya adlarını UTF-8 olmaya zorlamaz, bu yüzden kolayca çöp olabilir.


Bu açıklama, yerel yöneticilerin dışından gelen açıklamaları yansıtıyor gibi görünüyor, bunu yöneticilerin açıklaması tarafından verilen cevap olarak işaretleyeceğim. Son düzenlememi gör
mike-m

19

Bu gibi dosyaları / direcories silmek için bir yolu inode başvuruları gereğidir.

Geçerli dizindeki öğelerin düğümlerini bulmak için:

ls -i
14813568 mikeaâcnt

Bunu silmek için:

find . -inum 14813568 -delete

Lütfen 5. düzenlemeye bakınız.
mike-m

4
Hayır, bu dosyaları kendi düğümleriyle silmez. Bu, verilen inode için bir dosya ismi arar ve ardından dosyayı adına göre siler. Buraya yardımcı olamaz, çünkü zaten doğru adla bir girişimde bulunuldu (yanlış adla yapılan diğer girişimlerin yanında).
Gilles 'SO- kötülük olmayı bırak'

@Gilles - teknik olarak, inode dentry arar ve bir dosya adı döndürür, ancak kabul ediyorum.
mikeserv

1
@ Nicolai bana yardım etmiyor. Dizin boş değil mesajı geliyor.
diffracteD

1
Evet, hah, bununla ilgili komik bir hikaye: Silmeye çalıştığım dosya ?inode referansı gibi. O zaman nasıl silersin?
Nic Hartley

7

ASCII olmayan karakterleri komut satırında kullanmamalısınız, çünkü görebildiğiniz gibi, bir nedenden ötürü mutlaka dosya adına karşılık gelmeyeceklerdir (Unicode, vurgulu harfleri ifade etmenin çeşitli yollarını içerir). Gibi bir şey:

rm -rf mike*

dosya adı doğrudan kabuk tarafından üretildiğinden çalışmalıdır. Ancak yalnızca bir eşleşme olduğundan emin olun ( echo mike*onaylamak için bir ilk yapın).

İşe cdyararsa, o zaman neden söylemeli rmya da lssöylemeliyiz No such file or directory, böylece problem dosya sistemi düzeyinde olabilir.

Not: lsBir dizinin boş olup olmadığını bulmak için kullanmayın , fakat ls -a.

Dizin yine başka bir işlem tarafından kullanılabilir (bazı işlemlerin cwd'si de dahil). IMHO, bu yüzden hala “var” dır, ancak örneğin ls; lsofsize biraz bilgi verebilir, ancak NFS ile hangi makinenin kullandığını bulmanız gerekir. Özellikle NFS ile bu garip hatalara neden olabilir. ls -aÜst dizinde size .nfs*bazı durumlarda dosya / dizin gösterilebilir.

Ne zaman alırsın:

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

Dosyanın NFS önbelleğe alınması nedeniyle ve / veya başka bir işlem tarafından kullanıldığından, ancak ilişkili bilgiler olmadan kullanıldığından dizin tablosunda hala bulunduğundan şüpheleniyorum . Ne zaman lsçalışır dosyanın kendisinde bilgi almak için, kendisini artık yok dosyası olarak bir hata (yalnızca dizin tablosunda olduğu), dolayısıyla görüntülenen hatayı alır. Sonra lsdizin tablosunda olduğundan dosya adını verir. Bir durumda soru işaretlerinin olması ancak diğer durumda olmamanın nedeni lsIMHO’nun ( hata ile ilgisi olmayan) ekran hatası yüzündendir .


daha önce bir joker kullanmayı denedim, işe yaramadı ve bu girişimi soruma göndermedim, sonuçla güncelleyeceğim
mike-m

Üçüncü düzenlememe bakın. IMHO bunun nedeni NFS (muhtemelen yolsuzluk değil, ancak önbelleğe alma) ve muhtemelen başka bir işlemin dizini kullanmasıdır. Bazı durumlarda, kişi her şeyi yeniden başlatmaya ihtiyaç duyar (sunucu ve istemciler).
vinc17

Belki bu bazı şeyleri açıklayabilir, ancak testler yapmak için ayrıcalıklara sahip olmadığımdan emin olamıyorum. 5. düzenlemeye bakın.
mike-m

1
@ vinc17 Lütfen cevabınızda "EDIT" ifadesini kullanmayın, çünkü yeni okuyucu için bir anlam ifade etmiyor (zaten bir düzenleme geçmişi var)
Bernhard

iv bazı lsof çıktıları ekledi, size bir şey söyleyip söyleyemeyeceğinden emin değil,
mike-m

3

find'Nin -execdirektifini kullanarak şahsen test yaptım

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

Klasör doğru oluşturuldu ve doğru bir şekilde kaldırıldı.

@Georget tarafından belirtildiği gibi , GNU'nuz varsa daha da basit bir yöntem var find:

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

Ayrıca bu komutu test ettim ve düzgün çalışıyor


Ve eğer GNU’nun bulmasını kullanırsan, bir -deleteseçeneğin de var.
lgeorget

Lütfen 3. düzenlemeye bakın,
mike-m

1

Ben de aynı sorunu yaşadım, inanıyorum. Sorunu daha önce bir dosya adıyla gördüm . lsBu durumda dosyayı olarak görüntüledim â??, ancak silebildim rm ☃.

Bu beni yanlış adı doğru olana çevirmek için şu yöne götürdü:

İlk önce dosya adının baytını alın:

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

Daha sonra bu web baytının onaltılık girişini kullanarak unicode kod noktalarını almak için bu baytları UTF-8 olarak kodlayın: 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

Bunların hepsinin bayt sınırının altında olduğuna dikkat edin. Aşağıdaki baytları alıyoruz:

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

Bu diziyi UTF-8'de ele alırsak şunları elde ederiz:

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

Ve böylece, dosya adınız şudur: mikea⁄cntnormal bir öne değil, kesir çizgisiyle. Şimdi bu adı iletebilirsiniz rmdir.


Bu ustaca, eğer bir daha bununla karşılaşırsam, aklımda tutar. İyi bir. +1
mike-m

0

Dosya / klasör adının doğru hex kodunu aldıktan sonra (hangisi uygun görürse onu seçebilirim ls --show-control-chars | xxd), bash altında çalışırken bu karakterleri ele almak için bazı özel yapılar kullanılmalıdır:

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

Aksi takdirde ters eğik çizgiler vanilya ters eğik çizgi olarak değerlendirilir.


Lütfen düzenlememe bir göz atın (8. düzenleme)
mike-m

@ mike-m Tabii ki mevcut değil, çünkü lsçıktı verilerine yeni satır ekler ve "cnt" kopyalanır. Belki de cevabı doğrudan kopyalayıp yapıştırabilir ve etkili olup olmadığına bakabilirsiniz.
Abel Cheung

Hayır, yine de bu: `` `rl] $ rmdir $ 'mikea \ xc3 \ xa2 \ xc2 \ x81 \ xc2 \ x84cnt' rmdir:` mikeaâ \ 302 \ 201 \ 302 \ 204cnt 'kaldırılamadı: Böyle bir dosya veya dizin yok `` `
mike-m

Bu durumda, bir çok NFS sorunu ve yerel ayarların UTF8 olmayan baytların yanlış iletilmesini engelleyen sistem yardımcı programlarının bir araya gelmesi olasıdır. Ve inode çıkarma durumu daha da kötüleştirmiş gibi görünüyor. Şimdilik, düşünebilmemin tek yolu sisteminizi yerel olmayan bir ortama ayarlamak ( env değişkenleri için "C" yerelini kullanın ) LC_*ve LANGNFS'yi herhangi bir karakter kümesi seçeneği olmadan monte etmektir
Abel Cheung

0

Kullandığınız denediniz rm -rf ./mikeaâcntveya rm -rf "./mikeaâcnt"veya mutlak bir yol? Ayrıca, yerine rmdeneyin rmdir ./mikeaâcnt.


Sorunun bir kısmı, karakterlerin mikeaâcntdosya adı gibi görünmediği, fakat ne ls görüntülendiği, 3. düzenlemeye bakınız
mike-m

0

Bu dosyanın inode'unu aşağıdakilerle almayı denediniz mi stat:

stat mike*

Bu size inode numarasını (ve diğer verileri) vermeli ve sonra onu silmeyi deneyebilirsiniz.


iv statbehavour ile bir düzenleme ekledi ,
mike-m

0

Ben de benzer sorunlar yaşadım. Gnome, KDE veya bir tür Xwindow DM var mı? Eğer broser dosyanızı açıp dosyayı oradan çıkarın.

İşe yaramalı.

Komut satırından bir çözüm görmek isterdim, ama benim durumumda ve çok zaman kaybettikten sonra komut satırından nasıl çıkarılacağını anlamaya çalışırken, başka bir dosyayı nautilus'tan çıkarmak kadar basit olduğunu gördüm. başka bir dosya gezgini (gerçek şu ki, sadece nautilus ile denedim).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.