首页 > node 'fs' 为什么不支持访问'~/'开始的本地路径?

node 'fs' 为什么不支持访问'~/'开始的本地路径?

自己写一个小工具时发现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 干的事,fs 模块不会做如此的展开。
npm 上面有些包可以实现类似 bash 的展开,自己搜下即可。


这是个好问题。确实需要踩这么两回坑,才能认清系统中哪些机制是由哪些组件负责的。

处理命令行的 shell 毕竟是一个为了人类手动操作而生的东西…… shell 会对人类输入的命令做如下的处理:

请尝试以下的命令:(注:echo命令将其收到的所有参数,原封不动,用 1 个空格分隔打印出来)

echo A B C        # A B C
echo A  B  C      # A B C
echo A  B  \ C    # A B  C
echo A  B  " C"   # A B  C
echo ~            # /home/shamiao
echo \~           # ~
echo "~"          # ~
echo *            # 1.txt 2.txt 3.txt
echo "*"          # *

可以显然看出:具体的程序看不到、也不认识~*等字符。他们只识别绝对、无任何转义规则的纯粹的路径。人手打入的特殊字符早就被 shell 消化替换了,根本没有送达程序当中。

如果你真的(通过转义)把这些字符送进程序了,程序会认为这些字符本身,就真的是路径的一部分——即:程序认为真的存在一个名字是~的目录,其下有一个test.txt文件。这也就是你的程序出错的理由。

实际上你可以试着真的把~/test.txt建立起来,这样你的题主位的 node 程序就能读取到了:

mkdir "~"
touch "~"/test.txt
realpath "~"/test.txt # 这个命令会打印出 test.txt 的绝对路径

对于问题本身,脱离 shell 了~字符必然无法展开,也就无法使用。所以你需要在 node 中寻找其他手段,替代实现“获取主目录”这个目的。

这个手段是有的,在 node 4.0+ 中,你可以使用 函数直接获得主目录的绝对路径。

【热门文章】
【热门文章】