ænd*_*rük 6 linux zfs unicode files
我有一个名为akorg?
. 当软件对我的文件路径的文本编码做出错误假设时,Unicode 字符让我很头疼,所以我想从名称中删除它。
你会认为这很容易:
$ mv akorg? akorg
mv: cannot move ‘akorg?’ to a subdirectory of itself, ‘akorg/akorg?’
Run Code Online (Sandbox Code Playgroud)
但是——这很奇怪——它认为一个名为的文件夹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
...
Run Code Online (Sandbox Code Playgroud)
尽管如此,stat
否则说:
$ stat akorg
File: ‘akorg’
Size: 21 Blocks: 33 IO Block: 1536 directory
Device: 15h/21d Inode: 292128 Links: 11
...
Run Code Online (Sandbox Code Playgroud)
所以显然有一个不可见的文件夹。无论如何,我将删除它:
$ rmdir akorg
rmdir: failed to remove ‘akorg’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
对,那么。这到底是什么东西?
stat
返回两个相同的inodeakorg
和akorg?
。按该 inode 搜索仅返回akorg?
:
$ find . -maxdepth 1 -inum 292128
./akorg?
Run Code Online (Sandbox Code Playgroud)更多对“隐形”文件夹不起作用的东西:
$ 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
Run Code Online (Sandbox Code Playgroud)ak
only 返回akorg?/
。akorg
。这种对更明确的重命名尝试的反应令人费解和可怕:
$ mv --verbose --no-target-directory --no-clobber akorg? akorg
removed ‘akorg?’
Run Code Online (Sandbox Code Playgroud)
我不明白为什么它声称已删除akorg?
,或者为什么会尝试。幸运的是,ls
并stat akorg akorg?
揭示实际上什么都没有。这是strace。
为了排除编码怪癖的原因,我暂时给出akorg?
了一个中间名称:
$ mv --verbose --no-target-directory --no-clobber akorg? bananas
‘akorg?’ -> ‘bananas’
Run Code Online (Sandbox Code Playgroud)
这按预期工作,
$ 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
...
Run Code Online (Sandbox Code Playgroud)
但“隐形”文件夹仍然存在:
$ 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
...
Run Code Online (Sandbox Code Playgroud)
并且mv
仍然行为异常,当我尝试使用的名称akorg
:
$ mv --verbose --no-target-directory --no-clobber bananas akorg
removed ‘bananas’
Run Code Online (Sandbox Code Playgroud)当您使用 zsh 时,我建议使用 Tab 补全或 shell globbing(在删除之前始终使用 echo/ls)。如果这些不起作用,您有几个选择:
通过十六进制转储检查您的文件名并用于$'...'
输入它
% 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
%
Run Code Online (Sandbox Code Playgroud)
请注意,0a
上面的最后一个是输入末尾的换行符,所以我们不希望它出现在我们的名字中。
使用ls -i
得到的inode编号和使用find
将其删除
% touch akorg?
% ls -i
6128574 akorg?
% find . -inum 6128574
akorg?
% find . -inum 6128574 -delete
% ls
%
Run Code Online (Sandbox Code Playgroud)
您也find
可以按名称(无论哪种方式,先打印!)
使用ls -b
得到逃脱的名称,并输入它$'...'
(这适用于非打印字符,但似乎并没有影响到你的unicode的一个,所以这是为他人作参考)。
% ls
foo?bar
% ls -b
foo\rbar
% rm foo$'\r'bar
% ls
%
Run Code Online (Sandbox Code Playgroud)
这很奇怪。(这个“答案”一开始是一条评论;),后来变得有点长。)
\n\n看看它strace
看起来没有隐藏字符或类似的东西,否则我怀疑你会在例如中看到它(这应该会导致-1 ENOENT
而不是0
如果一切正常的话):
stat("akorg", {st_mode=S_IFDIR|0755, st_size=21, ...}) = 0\n
Run Code Online (Sandbox Code Playgroud)\n\n正如您在以下内容中所做的那样:
\n\nlstat("akorg\\342\\234\\275", {st_mode=S_IFDIR|0755, st_size=21, ...}) = 0\n
Run Code Online (Sandbox Code Playgroud)\n\n遇到一个邮件交换,其中一个人遇到了相反的问题。ls
列出文件,但stat
给出ENOENT
\xe2\x80\x93,尽管这是在 FreeBSD 上。
我不太了解zfs
,但是否可能某些同步、快照等失败并留下损坏的文件表?您是否创建/拥有一个名为akorg
您在尝试之前删除的目录mv
?
不知道您是否可以通过以下方式获取一些错误描述:
\n\n# zpool status -v\n
Run Code Online (Sandbox Code Playgroud)\n\n要尝试的一件事是检查反向 inode 查找(可以选择添加另一个d
)并检查path
:
# zdb -dddd <pool-name> <inode>\n
Run Code Online (Sandbox Code Playgroud)\n\n在名为的文件夹中baz
:
# zdb -dddd qqq 31\nObject lvl iblk dblk dsize lsize %full type\n 31 1 16K 512 1K 512 100.00 ZFS directory\n 264 bonus ZFS znode\ndnode flags: USED_BYTES USERUSED_ACCOUNTED \ndnode maxblkid: 0\npath /baz\nuid 1000\ngid 1000\natime Fri Jun 14 12:39:46 2013\nmtime Fri Jun 14 11:55:33 2013\nctime Fri Jun 14 11:55:33 2013\ncrtime Fri Jun 14 11:55:33 2013\ngen 1510\nmode 40775\nsize 2\nparent 3\nlinks 2\nxattr 0\nrdev 0x0000000000000000\nmicrozap: 512 bytes, 0 entries\n
Run Code Online (Sandbox Code Playgroud)\n\n在名为 的目录中foo
包含多个子目录,其中包括一个名为 的子目录akorg\xe2\x9c\xbd
:
Object lvl iblk dblk dsize lsize %full type\n 16 1 16K 512 1K 512 100.00 ZFS directory\n 264 bonus ZFS znode\ndnode flags: USED_BYTES USERUSED_ACCOUNTED \ndnode maxblkid: 0\npath /foo\nuid 1000\ngid 1000\natime Fri Jun 14 13:10:38 2013\nmtime Fri Jun 14 12:13:18 2013\nctime Fri Jun 14 12:13:18 2013\ncrtime Fri Jun 14 11:41:53 2013\ngen 1482\nmode 40775\nsize 6\nparent 3\nlinks 6\nxattr 0\nrdev 0x0000000000000000\nmicrozap: 512 bytes, 4 entries\n\n foo1 = 15 (type: Directory)\n foo2 = 18 (type: Directory)\n foo = 19 (type: Directory)\n akorg\xe2\x9c\xbd = 30 (type: Directory)\n
Run Code Online (Sandbox Code Playgroud)\n\n通过阅读ZFS Properties ,您对各种名称 mod 的设置zfs get all storage/home-ak-annex
看起来也很正常(据我所知)以及其他属性:
storage/home-ak-annex utf8only off -\nstorage/home-ak-annex normalization none -\nstorage/home-ak-annex casesensitivity sensitive -\n
Run Code Online (Sandbox Code Playgroud)\n\n如果您zfs
自己构建,您可以启用调试./configure --enable-debug
并使用上述内容-vvvv
,包括-bbbb
等。
最后你可以在 git 上打开一个新问题。
\n