自己写一个小工具时发现fs
包不支持'~/'路径。
> fs.writeFileSync('~/test.txt','helloWorld',"utf-8");
Error: ENOENT: no such file or directory, open '~/test.txt'
at Error (native)
at Object.fs.openSync (fs.js:584:18)
at Object.fs.writeFileSync (fs.js:1224:33)
at repl:1:4
at REPLServer.defaultEval (repl.js:248:27)
at bound (domain.js:280:14)
at REPLServer.runBound [as eval] (domain.js:293:12)
at REPLServer.<anonymous> (repl.js:412:12)
at emitOne (events.js:82:20)
at REPLServer.emit (events.js:169:7)
>
首先,我想了解下原因;
第二,有没有除了转换成绝对路径之外的方法?
这是个好问题。确实需要踩这么两回坑,才能认清系统中哪些机制是由哪些组件负责的。
处理命令行的 shell 毕竟是一个为了人类手动操作而生的东西…… shell 会对人类输入的命令做如下的处理:
将
~
、*
等表示特殊意义的字符,根据 shell 所定义的特殊意义解析并替换掉。注意:就连空格
都是特殊字符——表示分离开两个参数。
但是这样就造成了这些字符本身不能输入。所以还要通过一些转义手段,在必须输入这些字符本身时变通的加以支持。
shell 做完转换之后,把转换后的命令按(未经转义的)空格分开送给程序作为参数。
请尝试以下的命令:(注:
echo
命令将其收到的所有参数,原封不动,用 1 个空格分隔打印出来)可以显然看出:具体的程序看不到、也不认识
~
、*
等字符。他们只识别绝对、无任何转义规则的纯粹的路径。人手打入的特殊字符早就被 shell 消化替换了,根本没有送达程序当中。如果你真的(通过转义)把这些字符送进程序了,程序会认为这些字符本身,就真的是路径的一部分——即:程序认为真的存在一个名字是
~
的目录,其下有一个test.txt
文件。这也就是你的程序出错的理由。实际上你可以试着真的把
~/test.txt
建立起来,这样你的题主位的 node 程序就能读取到了:对于问题本身,脱离 shell 了
~
字符必然无法展开,也就无法使用。所以你需要在 node 中寻找其他手段,替代实现“获取主目录”这个目的。这个手段是有的,在 node 4.0+ 中,你可以使用
os.homedir()
函数直接获得主目录的绝对路径。