字符集和编码III: tricky cifs

CIFS是SMBFS的后继,SAMBA共享最好还是用CIFS内核模块,smbfs已经deprecated了(最近的内核已经没有smbfs module了)。

一台Linux服务器,上面同时有locale为GBK和UTF-8的中文文件名,其上samba服务器的设置为unix charset=cp936。本地的locale是utf8,在用cifs的情况下,怎样看到服务器上不同编码的文件名?

由于本地的locale是utf8,只要保证内核输出的串是UTF-8编码的。设服务器上GBK、UTF-8编码的文件名为\(s_1,s_2\),则它们在硬盘上被存储为\(\varphi_{cp936} \left( s_1 \right),\varphi_{utf8} \left( s_2 \right)\)。配置文件smb.conf中unix charset=cp936的选项使得samba服务器的输出、也就是本地内核的输入为:\[\varphi_{cp936}^{-1} \circ \varphi_{cp936} \left( s_1 \right) = s_1,\varphi_{cp936}^{-1} \circ \varphi_{utf8} \left( s_2 \right).\]

接下来,CIFS中iocharset=enc的意义和fat/vfat是相同的,即指定
\(\varphi_{enc}\)作用到输入串。所以很明显,若想看到\(s_1\),应选择iocharset=utf8(因为cifs中iocharset默认值取本地locale,因此该选项甚至不需要指定),此时内核输出的就是\(\varphi_{utf8} \left( s_1 \right)\);若想看到\(s_2\),则应选择iocharset=cp936,此时内核输出的是\[\varphi_{cp936} \circ \varphi_{cp936}^{-1} \circ \varphi_{utf8} \left( s_2 \right) = \varphi_{utf8} \left( s_2 \right),\]这正是我们所需要的结果。

这主要是为了说明我当时为什么mount.cifs时用了iocharset=cp936,当然这种情况是非常特殊的;大部分情况下,我们可以期望内核获得的是UNICODE串\(s_1,s_2\)(包括windows共享和samba服务),此时我们总选择iocharset=locale,这也是cifs的默认选项,因而在很多时候,我们除了指定用户名和密码,什么额外选项都不需要。

p.s. 觉得自己实在无聊得发指!!!

发表评论?

1 条评论。

发表评论


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">

Trackbacks and Pingbacks:

Switch to our mobile site