이 삭제 불가능한 디렉토리를 삭제하는 방법은 무엇입니까?


40

손상된 tar 파일을 압축 해제하고 삭제할 수없는 디렉토리로 끝났습니다. 삭제하려고하면 찾을 수없는 것처럼 보이지만 lsbash 및 python과 함께 존재합니다. 나는 그것을 삭제하려고 직후를 제외하고 비슷한 동작이 rm -rf, ls다음 그것을 나열, 그것을 찾을 수없는 불평 (후 아래 참조 rm -rf). 이 find명령은 파일이 있음을 보여 주지만 여전히 파일을 삭제하는 방법을 생각할 수 없습니다.
내 시도는 다음과 같습니다.

다음은 모두를 참조 ls하고 find우리가 디렉토리가 동의,

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

그러나 나는 그것을 삭제할 수 없습니다 :

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

나는 그것을 할 수 cd있고 비어 있습니다.

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


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

아래는 간단한 파일이 아니라 디렉토리이며 파일을 찾을 수 없다고 말한 ls후 재미있게 행동 rm -rf합니다.

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

따라서 이것은 python 시도이며 파일을 찾았지만 이름을 삭제할 수있는 이름으로 사용할 수 없습니다.

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'

탭 완성을 사용할 때도 픽업 이름을 사용할 수 없습니다.

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

파이썬이 bash로 보여주는 이름을 사용하면 다음과 같이됩니다.

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

이 손상된 디렉토리를 제거하기 위해 내가 할 수있는 일이 있습니까? 기본 파일 시스템 (NFS)은 작동하는 것으로 보이며 다른 문제는보고되지 않았으며 손상된 tar 파일까지 그러한 문제가 없었습니다.

편집 : 여기에 find자신의 -exec옵션을 사용하여 전화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]$

그러나 파일이 여전히 있습니다 (파일을 ls찾을 수 없다고 불평하지만 어쨌든 보여줍니다)

2 차 편집 :

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

동작은 여전히 ​​변경되지 않고 파일은 여전히 ​​존재합니다

3 차 편집 :

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

mikeaâcnt파이썬 시도의 출력을 보는 것보다 이름에 더 많은 것 같습니다 mikea\xc3\xa2\xc2\x81\xc2\x84cnt.

ls 출력

네 번째 편집 : 이것은 와일드 카드 시도입니다.

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

내 로케일 :

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 번째 편집 :

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

뿐만 아니라 동작은 지금 변경 ls하고 cd 이 작업을 수행 :

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.

이것은 삭제하는 시도 이후에 일어난, 내가 답변 한 제안은 NFS 문제가 될 수 있음을 생각하고 여기 vinc17에 의해.

6 번째 편집 : lsofls -a

rl] $ / usr / sbin / lsof mikeaâ ^ Á ^ Äcnt lsof : mikeaâ \ xc2 \ x81 \ xc2 \ x84cnt의 상태 오류 : 해당 파일 또는 디렉토리가 없습니다.

위의 잘못된 lsof호출은 다음과 같습니다. (rl은 상위 디렉토리입니다)

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 번째 편집 : 이동이 작동하지 않습니다 (이 모든 것을 시도했지만 출력을 저장하지 않았습니다) . 파일 ls과 동일한 문제 rm가 있습니다.

8 편집 : 이것은 제안 된대로 16 진수 문자를 사용하고 있습니다 :

 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 번째 편집 : stat명령 :

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

그것은 모든 출력에서 ​​훨씬 더 가능성이있는 것으로 보입니다. 댓글에서 제안한 것처럼 버그 또는 다른 NFS 오작동이 있습니다.

편집 10 : 이것은 큰, 출력 또는이 두 명령 이후의 strace 출력입니다.

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

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

편집 11 : 위의 전에 rmdir나는 cd디렉토리에 들어갈 수 있음을 알았지 만 어제와 마찬가지로 다시 rmdir할 수 없었 cd습니다. ... 파일이 존재 :

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

최종 편집 : 이것에 대한 로컬 관리자를 보았고 서버 자체에 로그온하고 서버에서 삭제하여 처리했습니다. 그들로부터의 설명은 이름의 문자 세트가 부적절 할 때 문제가 될 수 있다는 것입니다.


옵션을 find사용하는 대신 다른 명령으로 출력을 파이핑하는 이유가 exec있습니까?
HalosGhost

@HalosGhost 이유가 없습니다, 질문에 대한 추가 정보 편집을 참조하십시오
mike-m

2
유닉스와 리눅스에 대한 경험이 거의없는 사람은 다음과 같은 아이디어를 얻습니다 : 기호를 사용하지 않고 디렉토리 이름을 다른 것으로 바꾸십시오 mv. 그 후에 삭제할 수 있습니다. 또는 디렉토리를 더 깊은 폴더 레벨 (와일드 카드 사용)로 이동 한 다음 이동 한 폴더를 삭제 해보십시오.
Nzall

4
디렉토리가 클라이언트의 메모리에만 존재하고 오랫동안 서버에 사라 졌다고 생각합니다. 마운트를 해제했다가 다시 마운트 해 보셨습니까? 클라이언트 재부팅을 시도 했습니까? 다른 고객에게도 표시됩니까?
kasperd

6
@ mike-m NFS 서버에서 아마도 NFS 버그에 부딪힌 것 같습니다. 서버에서 파일 시스템이 손상되었거나 파일 시스템이 손상되었습니다. NFS 서버 관리자가 처리 할 때까지 기다리는 것 외에 다른 작업을 할 수 있을지 의심됩니다.
derobert

답변:


11

이 글 에서 발췌 한 다음 발췌문은 해당 디렉토리의 삭제를 거부하는 이유를 설명합니다.

NFSv4에서는 모든 파일 이름을 UTF-8을 사용하여 교환해야합니다. NFSv4 사양 인 RFC 3530에 따르면 파일 이름은 1.4.3 절에서 UTF-8로 인코딩되어야한다고합니다.“약간의 출발에서 파일 및 디렉토리 이름은 국제화의 기본 사항을 처리하기 위해 UTF-8로 인코딩됩니다.”같은 텍스트 최신 NFS 4.1 RFC (RFC 5661) 섹션 1.7.3에도 나와 있습니다. 현재 Linux NFS 클라이언트는 현재 로케일에서 UTF-8 로의 변환없이 파일 이름을 그대로 전달합니다. 비 UTF-8 파일 이름을 사용하면 원격 NFSv4 시스템을 사용하는 시스템에서 실제 문제가 될 수 있습니다. NFS 사양을 따르는 모든 NFS 서버는 비 UTF-8 파일 이름을 거부해야합니다. 따라서 파일을 실제로 Linux 클라이언트에서 NFS 서버로 저장할 수있게하려면 현재 UTF-8 파일 이름을 사용해야합니다. 다시 말해,

UTF-8은 장기적인 접근 방식입니다. 시스템은 기존의 많은 인코딩뿐만 아니라 UTF-8도 지원해야하므로 사람들은 UTF-8로 전환 할 수 있습니다. “UTF-8을 어디에나 사용”하려면 UTF-8을 지원하도록 모든 도구를 업데이트해야합니다. 몇 년 전, 이것은 큰 문제 였지만, 2011 년 현재 이것은 본질적으로 해결 된 문제이며, 궤적은 소수의 트레일 링 시스템에서 매우 분명하다고 생각합니다.

모든 바이트 시퀀스가 ​​유효한 UTF-8 인 것은 아니며 표시 방법을 알아 내고 싶지는 않습니다. 커널이 이러한 제한을 적용하여 UTF-8 파일 이름 만 허용하면 문제가 없습니다. 모든 파일 이름은 유효한 UTF-8이됩니다. Markus Kuhn의 utf8_check C 함수는 시퀀스가 ​​유효한 UTF-8인지 신속하게 판별 할 수 있습니다.

파일 시스템은 파일 이름이 표준을 충족하도록 요구해야합니다. 사람을 제어해야하는 악의적 인 요구 때문이 아니라 단순히 이름이 나중에 항상 올바르게 표시 될 수 있도록하기 위해서입니다. 표준이 없기 때문에 사용자가 일을 더 어렵게 만들 수 있습니다. 그러나 파일 시스템은 파일 이름을 UTF-8로 강제하지 않으므로 가비지를 쉽게 가질 수 있습니다.


이것은 로컬 관리자의 설명을 반영하는 것 같습니다. 관리자 설명의 답변으로 표시합니다. 내 최종 편집 참조
mike-m

19

이와 같은 파일 / 디렉토리를 삭제하는 한 가지 방법은 inode-reference입니다.

현재 디렉토리의 요소에 대한 inode를 찾으려면 다음을 수행하십시오.

ls -i
14813568 mikeaâcnt

이것을 삭제하려면 :

find . -inum 14813568 -delete

5 번째 편집을 참조하십시오.
mike-m

4
아니요, 이것은 inode에 의해 파일을 삭제하지 않습니다. 주어진 inode에 대한 파일 이름을 찾은 다음 해당 이름으로 파일을 삭제합니다. 이름이 잘못된 다른 시도와 함께 이미 올바른 이름으로 시도 했으므로 여기에서는 도움이되지 않습니다.
Gilles 'SO- 악마 그만해'

@Gilles-기술적으로 inode dentry를 찾고 파일 이름을 반환하지만 동의합니다.
mikeserv

1
@Nicolai는 나를 도와주지 않습니다. 비어 있지 않은 디렉토리 메시지가 나타납니다.
diffracteD

1
예, 이것에 관한 재미있는 이야기 : 삭제하려는 파일 ?은 inode 참조로 사용됩니다. 그런 다음 어떻게 삭제합니까?
Nic Hartley

7

명령 줄에서 ASCII가 아닌 문자를 사용해서는 안됩니다. 어떤 이유로 든 파일 이름과 일치하지 않을 수도 있기 때문입니다 (유니 코드에는 악센트 부호 문자를 표현하는 다양한 방법이 있음). 다음과 같은 것 :

rm -rf mike*

파일 이름이 셸에서 직접 생성되므로 작동해야합니다. 그러나 일치하는 항목이 하나만 있는지 확인하십시오 ( echo mike*먼저 확인).

음, 경우 cd작품, 왜 이유가 없다 rm거나 ls말을해야 No such file or directory문제가 파일 시스템 수준에서 할 수있다 그래서.

참고 : ls디렉토리가 비어 있는지 확인하는 데 사용하지 말고를 사용하십시오 ls -a.

다른 프로세스에서 디렉토리를 계속 사용할 수 있습니다 (일부 프로세스의 cwd 인 경우 포함). IMHO, 이것이 여전히 "존재"하지만 오류를 생성 할 수있는 이유입니다 (예 : ls; lsof몇 가지 정보를 제공 할 수도 있지만 NFS를 사용하면 어떤 시스템에서 정보를 사용해야하는지 알아야합니다. 특히 NFS의 경우 이상한 오류가 발생할 수 있습니다. ls -a부모 디렉토리에 .nfs*파일 / 디렉토리가 표시 되는 경우가 있습니다.

당신이 얻을 때:

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

NFS 캐싱 및 / 또는 다른 프로세스에서 사용하지만 관련 정보가 없어서 파일이 여전히 디렉토리 테이블에 존재하는 것 같습니다 . 때 ls시도가 파일 자체에 대한 정보를 얻으려면, 그 자체가 더 이상 존재하지 않는 파일과 오류 (그것은 단지 디렉토리 테이블에), 따라서 표시된 오류를 가져옵니다. 그런 다음 ls파일 이름이 디렉토리 테이블에 있으므로 출력합니다. 한 경우에 물음표가 있지만 다른 경우에는 물음표가 없다는 사실은 lsIMHO 의 표시 버그 (문제와 무관) 때문입니다.


나는 그것이 작동하지 않았다, 와일드 카드 이전 시도했고, 나는 결과로 업데이트됩니다, 내 질문에 그 시도를 작성하는 데 실패
마이크-m를

내 세 번째 편집을 참조하십시오. IMHO 이것은 NFS (아마 손상되지는 않지만 캐싱이 잘못됨) 및 다른 프로세스가 디렉토리를 사용하고 있기 때문입니다. 어떤 경우에는 모든 것을 다시 부팅해야합니다 (서버 및 클라이언트).
vinc17

어쩌면 이것은 설명 할 수 있지만 테스트를 위해 그것을 내려야 할 특권이 없기 때문에 확신 할 수 없습니다. 5 번째 편집을 참조하십시오.
mike-m

1
@ vinc17 답변에 "EDIT"를 사용하지 마십시오. 새로운 독자에게는 이치에 맞지 않기 때문에 (이미 편집 히스토리가 있음)
Bernhard

iv 어떤 lsof 출력을 추가
mike-m

3

find-exec지시문을 사용하여 개인적으로 테스트했습니다 .

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

폴더가 올바르게 작성되고 올바르게 제거되었습니다.

@Igeorget 에서 지적했듯이 GNU가 있다면 더 간단한 방법이 있습니다 find.

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

또한이 명령을 테스트했으며 올바르게 작동합니다.


그리고 GNU의 find를 사용하면 -delete옵션도 있습니다.
lgeorget

3 번째 수정 내용 참조
mike-m

1

나는 같은 문제를 겪었다 고 믿는다. 파일 이름이 이전에 문제가 발생했습니다 . ls이 경우 파일을로 표시 â??했지만을 (를) 사용하여 삭제할 수있었습니다 rm ☃.

이로 인해 잘못된 이름을 올바른 이름으로 변환하는 방법은 다음과 같습니다.

먼저 파일 이름의 바이트를 얻습니다.

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

그런 다음이 웹 사이트의 16 진수 입력을 사용하여 유니 코드 코드 포인트를 얻으려면이 바이트를 UTF-8로 디코딩 하십시오. 예 : 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

이것들은 모두 바이트 경계 아래에 있습니다. 다음 바이트를 얻습니다.

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

이 시퀀스를 UTF-8로 처리하면 다음과 같은 결과를 얻습니다.

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

따라서 파일 이름은 다음 mikea⁄cnt과 같습니다 . 일반 슬래시 대신 분수 슬래시가 있습니다. 이 이름을에 전달할 수 있습니다 rmdir.


내가 이것을 다시 만난다면, 이것을 명심하십시오. 좋은 것. +1
mike-m

0

파일 / 폴더 이름의 올바른 16 진수 코드를 얻은 후에 (적절한 방법을 사용하고을 선택할 수 있음 ls --show-control-chars | xxd) bash에서 실행할 때 이러한 문자를 처리하는 데 특별한 구조를 사용해야합니다.

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

그렇지 않으면 백 슬래시는 바닐라 백 슬래시로 처리됩니다.


나의 편집 (8 번째 편집)을보십시오
mike-m

@ mike-m 물론 존재하지 않습니다 ls. 출력 데이터에 개행 문자가 포함되어 있고 "cnt"가 복제 되었기 때문 입니다. 어쩌면 당신은 직접 답변을 복사하여 붙여 넣을 수 있고 효과가 있는지 볼 수 있습니까?
Abel Cheung

아니, 여전히 :```rl] $ rmdir $ 'mikea \ xc3 \ xa2 \ xc2 \ x81 \ xc2 \ x84cnt'rmdir :`mikeaâ \ 302 \ 201 \ 302 \ 204cnt '를 제거하지 못했습니다 : 그러한 파일이나 디렉토리가 없습니다 ```
mike-m

이 경우 NFS 문제와 대부분의 시스템 유틸리티가 잘못된 비 UTF8 바이트를 전달하지 못하게하는 로케일의 조합 일 가능성이 높습니다. 그리고 inode 제거가 상황을 악화시킨 것처럼 보입니다. 지금은 내가 생각할 수있는 유일한 방법은 (사용 "C"로케일 로케일없는 환경으로 시스템을 설정하는 것입니다 LC_*LANG모든 문자 집합 옵션없이 ENV 변수) 및 NFS 마운트
아벨 청

0

rm -rf ./mikeaâcnt또는 rm -rf "./mikeaâcnt"또는 절대 경로를 사용해 보셨습니까 ? 또한 대신에 rm시도하십시오 rmdir ./mikeaâcnt.


문제의 일부에 문자가 있다는 것입니다 mikeaâcnt파일 이름이 될,하지만하지 않는 것처럼 보인다 ls 디스플레이, 3 편집 참조
마이크-m

0

해당 파일의 inode를 stat다음 과 같이 얻으려고 했습니까?

stat mike*

그것은 당신에게 inode 번호 (및 다른 데이터)를 줄 것이고, 그것을 삭제하려고 시도 할 수 있습니다.


iv는 stat행동 으로 편집을 추가했습니다
mike-m

0

비슷한 문제가있었습니다. 그놈, KDE 또는 Xwindow DM이 있습니까? 파일 브라우저를 열고 거기에서 파일을 제거하십시오.

작동해야합니다.

명령 줄에서 솔루션을보고 싶지만 제 경우에는 명령 줄에서 솔루션을 제거하는 방법을 찾으려고 많은 시간을 잃은 후 노틸러스 또는 다른 파일을 제거하는 것만 큼 간단하다는 것을 알았습니다. 다른 파일 탐색기 (진실은 노틸러스로만 시도한 것입니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.