几个与文件系统有关的坑
入职 Monkii 后,按自己的喜好选了 iMac 作为工作环境。不料一上来就给我安排了一个用 .Net 作后端的项目,让我负责前端。人在江湖身不由己,只好折腾起 Windows 。
¶Case-sensitive
在这之前想做一次系统迁移,把之前配置好的环境从另一台 iMac 弄过来。苹果的迁移助手非常厉害,直接通过 Wifi 就可以迁移系统。不过这次不灵了!迁移助手无法在 Case-sensitve Filesytem 与 Case-insensitve Filesystem 之间做系统迁移!这才意识到,在用的这台电脑在装机的时候被老大搞成了大小写敏感的文件系统。
¶Steam
以前从来没注意这个问题,觉得这没什么问题,大小写敏感还增加了文件命名空间,不是挺好吗。直到我装了 Steam 后发现怎么也打不开,一直卡在登陆界面。
通过终端运行 Steam ,看到了打印出来的日志:
Errors in public/subpanelwelcomeintro.res:
error loading file 'public/subpanelwelcomeintro.res', no such file
Errors in public/subpanelwelcomecreatenewaccount.res:
error loading file 'public/subpanelwelcomecreatenewaccount.res', no such file
Errors in public/subpanelwelcomecreatenewaccountaccountname.res:
error loading file 'public/subpanelwelcomecreatenewaccountaccountname.res', no such file
Errors in public/subpanelwelcomecreatenewaccountemail.res:
error loading file 'public/subpanelwelcomecreatenewaccountemail.res', no such file
...
才发现 Steam 的加载器全部以小写文件名加载文件,而目录中的文件名则是驼峰式的,(e.g. SubPanelWelcomeIntro.res)。只好暂时写个脚本将所有文件名转成小写,终于可以正常打开 Steam 了。不过在每次 Steam 更新后,都得重做这一步骤。
¶Webpack
BTW,自动化打包工具在 Case-sensitive 的文件系统上常常也会出各种问题。以下是在项目中使用 ScrollMagic.js 时遇到的警告:
// include ScrollMagic library and its jQuery Plugin
require('scrollmagic')
require('scrollmagic/scrollmagic/uncompressed/plugins/jquery.ScrollMagic')
在打包的时候会出现下面的提示:
WARNING in ./~/ScrollMagic/scrollmagic/uncompressed/ScrollMagic.js
There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:
* G:\Sites\Secret-Project\node_modules\ScrollMagic\scrollmagic\uncompressed\ScrollMagic.js
Used by 1 module(s), i. e.
G:\Sites\Secret-Project\node_modules\scrollmagic\scrollmagic\uncompressed\plugins\jquery.ScrollMagic.js
* G:\Sites\Secret-Project\node_modules\scrollmagic\scrollmagic\uncompressed\ScrollMagic.js
Used by 1 module(s), i. e.
G:\Sites\Secret-Project\node_modules\babel-loader\lib\index.js!G:\Sites\Secret-Project\src\entry-client.js
原因是 jquery.ScrollMagic.js 使用 UMD 定义库引用的时候,使用了驼峰式:define(['ScrollMagic', 'jquery'], factory);
,所以 Webpack 给出了警告。
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['ScrollMagic', 'jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
factory(require('scrollmagic'), require('jquery'));
} else {
// Browser global
factory(root.ScrollMagic, root.jQuery);
}
}(...));
解决办法是全部使用小写。不过还好这个项目放在 NTFS 分区,暂时正常。
¶ExFAT
iMac 用的是 128G 的 SSD,有点小。分区装个 Windows 后就不顶用了。于是从同事那弄了个 128G 的扩展 SSD 。这货只能格式化成 ExFAT 或 NTFS 格式。不过 ExFAT 这个文件系统可以同时在 macOS 和 windows 支持读和写,凑合用吧。
¶Block Size
后来才发现,ExFAT 的最小文件块大小居然是 512KB!对于前端来说简直是恶梦!因为前端会使用 NPM 管理大量的第三方库,这些库基本上就是成千上万个小文件。感受一下数据:
Contains: 15,766 Files, 2,028 Folders
Size:72.9 MB (76,526,168 bytes)
Size on disk: 1.93 GB (2,083,258,368 bytes)
70M 左右的文件放在 ExFAT 上居然占了接近 2G,而在 NTFS 上只有不到 90M 。
¶Symlink
另一个坑是,ExFAT 是不支持软链的。一些需要 Symlink 支持的项目没办法放在 ExFAT 文件系统中。像是使用 broccoli.js 打包的前端库,还有运行在 Vagrant 里,需要与外部文件系统建立联系的时候:
ln: creating symbolic link `dist`: Protocol error
最后只好再在这个扩展 SSD 上分了个 NTFS 的区来用。
¶File Permissions
September 9, 2019 补充: 在一次处理 Vagrant 链接问题的时候发现放在 ExFAT 分区的 vagrant.d 配置目录里的 insecure_private_key 无法使用,因为权限给的太宽:
D:\.vagrant.d>ssh-keygen -y -f insecure_private_key > ./insecure_public_key.pub
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for 'insecure_private_key' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "insecure_private_key": bad permissions
并且无法修改,后来一查才知道,原来 ExFAT 是没有权限控制的,相当于整个硬盘都是0777
。解决方案是将其移动到其它盘符下再处理。
所以请不要把重要的文件放在 ExFAT 盘中,尤其是密钥。
¶Summary
文件系统还是尽量使用大小写不敏感为好。ExFAT 之类的 SSD 比较适合放媒体文件,不适合存放代码。