배경
이라는 폴더가 있습니다 akorg✽
. 이 유니코드 문자는 소프트웨어가 내 파일 경로의 텍스트 인코딩에 대해 잘못된 가정을 할 때 골치 아픈 일이 되므로 이름에서 이를 제거하고 싶습니다.
질문
이것이 쉽다고 생각할 수도 있습니다:
$ mv akorg✽ akorg
mv: cannot move ‘akorg✽’ to a subdirectory of itself, ‘akorg/akorg✽’
그러나 이것은 이상합니다. 이름이 지정된 폴더가 akorg
이미 존재한다고 생각합니다. 나는 하나도 없다고 확신합니다.
$ ls -la
total 699K
drwxr-xr-x 15 ak ak 15 Jun 12 17:34 .
drwxr-xr-x 57 ak ak 4.0K Jun 12 17:35 ..
drwxr-xr-x 11 ak ak 21 Jun 12 16:58 akorg✽
drwxr-xr-x 2 ak ak 2 May 28 20:47 Desktop
...
그런데 stat
또 이런 말이 있습니다.
$ stat akorg
File: ‘akorg’
Size: 21 Blocks: 33 IO Block: 1536 directory
Device: 15h/21d Inode: 292128 Links: 11
...
분명히 보이지 않는 폴더가 있는 것 같습니다. 어쨌든 제거하겠습니다.
$ rmdir akorg
rmdir: failed to remove ‘akorg’: No such file or directory
그럼요. 도대체 이게 뭐죠?
내가 지금까지 아는 것
- 나는 사용하고있다안정적인 릴리스~의Linux의 ZFS. 이것은zpool 상태 및 zfs 등록 정보.
stat
akorg
및 모두에 대해 동일한 inode를 반환합니다akorg✽
. 이 인덱스 노드로 검색하면 다음만 반환됩니다akorg✽
.$ find . -maxdepth 1 -inum 292128 ./akorg✽
"보이지 않는" 폴더에서는 작동하지 않는 추가 작업:
$ rm akorg rm: cannot remove ‘akorg’: Is a directory $ unlink akorg unlink: cannot unlink ‘akorg’: Is a directory $ mv akorg akorg_temp mv: cannot move ‘akorg’ to ‘akorg_temp’: No such file or directory
- Bash 4.2.45와 zsh 5.0.0에서 동일한 결과를 얻었습니다. 두 경우 모두 탭 완성
ak
만 반환됩니다akorg✽/
. - 이것스트레스처음 이름 바꾸기 시도를 통해 이름을 올바르게 입력했음이 확인되었으며 이름이 기존 폴더에 의해 차단되었습니다
akorg
. 보다 명시적인 이름 변경 시도에 대한 응답은 복잡하고 끔찍했습니다.
$ mv --verbose --no-target-directory --no-clobber akorg✽ akorg removed ‘akorg✽’
왜 제거했다고 주장하는지
akorg✽
, 왜 시도하는지 이해가 되지 않습니다. 다행히 실제로는 아무것도 사라지지 않은ls
것으로stat akorg akorg✽
나타났습니다. 이것은스트레스.akorg✽
이상한 인코딩을 배제하기 위해 지금은 중간 이름을 지정했습니다 .$ mv --verbose --no-target-directory --no-clobber akorg✽ bananas ‘akorg✽’ -> ‘bananas’
예상대로,
$ ls -la total 715K drwxr-xr-x 16 ak ak 16 Jun 13 15:11 . drwxr-xr-x 57 ak ak 4.0K Jun 13 14:03 .. drwxr-xr-x 11 ak ak 21 Jun 12 16:58 bananas drwxr-xr-x 2 ak ak 2 May 28 20:47 Desktop ...
그러나 "invisible" 폴더는 여전히 존재합니다:
$ stat bananas akorg File: ‘bananas’ Size: 21 Blocks: 33 IO Block: 1536 directory Device: 15h/21d Inode: 292128 Links: 11 ... File: ‘akorg’ Size: 21 Blocks: 33 IO Block: 1536 directory Device: 15h/21d Inode: 292128 Links: 11 ...
mv
해당 이름을 사용하려고 하면 여전히 이상하게 동작합니다akorg
.$ mv --verbose --no-target-directory --no-clobber bananas akorg removed ‘bananas’
답변1
zsh를 사용하는 경우 탭 완성 또는 쉘 와일드카드를 사용하는 것이 좋습니다(삭제하기 전에 항상 echo/ls 사용). 그래도 문제가 해결되지 않으면 다음과 같은 몇 가지 옵션이 있습니다.
Hex Dump를 통해 파일 이름을 확인하고 $'...'
입력하는 데 사용합니다.
% touch akorg✽
% ls | grep akorg | hexdump -C
00000000 61 6b 6f 72 67 e2 9c bd 0a |akorg....|
00000009
% ls $'akorg\xe2\x9c\xbd'
akorg✽
% rm $'akorg\xe2\x9c\xbd'
% ls
%
위의 마지막 문자는 0a
입력 끝에 있는 개행 문자이므로 이름에 표시되는 것을 원하지 않습니다.
ls -i
inode 번호를 가져오고 삭제하는 데 사용 됩니다 find
.
% touch akorg✽
% ls -i
6128574 akorg✽
% find . -inum 6128574
akorg✽
% find . -inum 6128574 -delete
% ls
%
이름으로 갈 수도 있습니다 find
(어느 쪽이든 먼저 인쇄하세요!).
이스케이프된 이름을 가져와 ls -b
입력합니다 $'...'
(인쇄되지 않는 문자에 대해서는 작동하지만 유니코드 문자에는 영향을 주지 않는 것 같으므로 다른 사람이 참조할 목적으로만 사용).
% ls
foo?bar
% ls -b
foo\rbar
% rm foo$'\r'bar
% ls
%
답변2
이것은 매우 이상합니다.(이 "답변"은 주석으로 시작되었습니다;) 그러다가 조금 길어졌습니다. )
strace
숨겨진 문자나 이와 유사한 것이 없는지 확인하십시오 . 그렇지 않으면 다음과 같이 표시될 것입니다( 모든 것이 제대로 작동하는 경우 결과가 표시되어야 함) -1 ENOENT
.0
stat("akorg", {st_mode=S_IFDIR|0755, st_size=21, ...}) = 0
다음과 같이 합니다.
lstat("akorg\342\234\275", {st_mode=S_IFDIR|0755, st_size=21, ...}) = 0
한 사람이 메일 교환을 겪었습니다.반대 질문. ls
파일을 나열하지만 stat
제공됩니다 ENOENT
. 비록 FreeBSD에 있지만.
잘 이해가 안가지만 zfs
, 일부 동기화, 스냅샷 등이 실패하여 손상된 파일 테이블이 남을 가능성이 있나요? akorg
시도하기 전에 삭제한 디렉토리를 생성했거나 가지고 있습니까 mv
?
다음을 통해 오류 설명을 얻을 수 있는지 확실하지 않습니다.
# zpool status -v
시도해 볼 수 있는 한 가지는 역방향 inode 조회를 확인하고(선택적으로 다른 항목을 추가 d
) 다음을 확인하는 것입니다 path
.
# zdb -dddd <pool-name> <inode>
폴더 이름 baz
:
# zdb -dddd qqq 31
Object lvl iblk dblk dsize lsize %full type
31 1 16K 512 1K 512 100.00 ZFS directory
264 bonus ZFS znode
dnode flags: USED_BYTES USERUSED_ACCOUNTED
dnode maxblkid: 0
path /baz
uid 1000
gid 1000
atime Fri Jun 14 12:39:46 2013
mtime Fri Jun 14 11:55:33 2013
ctime Fri Jun 14 11:55:33 2013
crtime Fri Jun 14 11:55:33 2013
gen 1510
mode 40775
size 2
parent 3
links 2
xattr 0
rdev 0x0000000000000000
microzap: 512 bytes, 0 entries
foo
이름이 지정된 하위 디렉토리를 포함하여 이름이 지정된 디렉토리 내에 여러 하위 디렉토리가 포함되어 있습니다 akorg✽
.
Object lvl iblk dblk dsize lsize %full type
16 1 16K 512 1K 512 100.00 ZFS directory
264 bonus ZFS znode
dnode flags: USED_BYTES USERUSED_ACCOUNTED
dnode maxblkid: 0
path /foo
uid 1000
gid 1000
atime Fri Jun 14 13:10:38 2013
mtime Fri Jun 14 12:13:18 2013
ctime Fri Jun 14 12:13:18 2013
crtime Fri Jun 14 11:41:53 2013
gen 1482
mode 40775
size 6
parent 3
links 6
xattr 0
rdev 0x0000000000000000
microzap: 512 bytes, 4 entries
foo1 = 15 (type: Directory)
foo2 = 18 (type: Directory)
foo = 19 (type: Directory)
akorg✽ = 30 (type: Directory)
다양한 이름 모드에 대한 설정 zfs get all storage/home-ak-annex
도 (내가 알 수 있는 한) 정상으로 보이며 다른 속성도 읽은 대로 보입니다.ZFS 속성:
storage/home-ak-annex utf8only off -
storage/home-ak-annex normalization none -
storage/home-ak-annex casesensitivity sensitive -
zfs
직접 빌드 하는 경우 디버깅을 활성화 ./configure --enable-debug
하고 위의 -vvvv
내용 -bbbb
등을 사용할 수 있습니다.
마지막으로새로운 질문자식에.
답변3
나는 당신이 보이지 않는 디렉토리가 없고 대신 stat
파일 이름이좋다 akorg
화면에 나타날 때.
두 가지 가능한 솔루션:
탭 완성 기능이 있는 셸(zsh 또는 bash)을 사용하세요. 프롬프트를 따르십시오:
rm -rf akorg<tab>
. Zsh는 최소한 파일 이름을 완성하고 필요한 경우 쉘 특수 문자를 이스케이프합니다.약간 위험한 한 줄짜리 :
rm -rf akorg?
예를 들어 다음과 같이 #2를 수동으로 수행할 수 있습니다 ls -1 > filenames
. "filenames"라는 파일에 대해 일부 텍스트 편집기를 사용하여 문제의 디렉터리를 제외한 모든 줄을 삭제합니다. rm -rf
줄에 접두어를 추가합니다. 편집기를 종료합니다. 쉘 스크립트로 실행됩니다:sh filenames