运行节点 bin 脚本时确定命令行工作目录
Posted
技术标签:
【中文标题】运行节点 bin 脚本时确定命令行工作目录【英文标题】:Determine command line working directory when running node bin script 【发布时间】:2012-08-27 15:17:21 【问题描述】:我正在创建一个节点命令行界面。全局安装,使用bin文件执行。
我计划在我正在处理的文件的根目录中打开一个命令窗口,然后只运行命令但是我无法确定当前的工作目录,因为process.cwd()
正在返回节点的目录包裹。我最初假设,由于代码是使用批处理文件作为包装器执行的(这就是 bin 文件在开始时没有节点的情况下执行的方式),所以这是不可能的,但 coffee-script 设法做到了。看了下coffee-script源码,没看懂(经验不够)。
要自己测试它,请使用此 package.json 文件创建一个包:
"name": "test-package",
"version": "1.0.0",
"bin":
"test-package": "./bin/test-package"
,
"main": "/lib/test"
bin 中的这个测试包文件:
#!/usr/bin/env node
var path = require('path');
var fs = require('fs');
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');
require(lib + '/test');
任何人都可以对此有所了解。
然后尝试获取 lib/test 中的命令行目录。
【问题讨论】:
【参考方案1】:process.cwd()
返回执行命令的目录(不是节点包的目录),如果它没有被应用程序内部的 'process.chdir' 更改。
__filename
返回文件所在文件的绝对路径。
__dirname
返回__filename
目录的绝对路径。
如果您需要从模块目录加载文件,则需要使用相对路径。
require('../lib/test');
而不是
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');
require(lib + '/test');
它总是相对于它调用的文件,不依赖于当前的工作目录。
【讨论】:
process.chdir()
之后,有没有办法拿到原版?
@reergymerej 您可能希望在执行 chdir() 之前先存储 cwd(例如,var originalCwd = process.cwd();
然后执行您的 process.chdir()
,然后您可以返回原始数据)。
../lib/test
便携吗?
没有。它不是一个可移植的解决方案,因为 Windows 使用反斜杠。因此,如果您尝试在 Windows 中运行它,它将无法正常工作。
其实对于 NodeJS 这都是一样的。即使在 Windows 上,您也可以方便地以 Unix 方式要求相对路径。所以../lib/test
是可移植的,而Windows 对应的..\lib\test
不是...【参考方案2】:
或者,如果您只想获取当前 NodeJS 脚本的当前目录,您可以尝试类似这样的简单操作。请注意,这在 Node CLI 本身中不起作用:
var fs = require('fs'),
path = require('path');
var dirString = path.dirname(fs.realpathSync(__filename));
// output example: "/Users/jb/workspace/abtest"
console.log('directory to start walking...', dirString);
【讨论】:
【参考方案3】:当前工作目录
要获取当前工作目录,可以使用:
process.cwd()
但是,请注意,某些脚本,尤其是 gulp,会将当前工作目录更改为 process.chdir()
。
节点模块路径
您可以通过以下方式获取当前模块的路径:
__filename
__dirname
原始目录(启动命令的位置)
如果您从命令行运行脚本,并且想要运行脚本的原始目录,无论脚本当前在哪个目录中运行,您都可以使用:
process.env.INIT_CWD
使用 NPM 脚本时的原始目录
有时需要在当前目录而不是项目的根目录中运行 NPM 脚本。
此变量在 npm 包脚本中可用:
$INIT_CWD.
您必须运行最新版本的 NPM。如果此变量不可用,请确保 NPM 是最新的。
这将允许您访问 package.json 中的当前路径,例如:
scripts:
"customScript": "gulp customScript --path $INIT_CWD"
【讨论】:
process.env.INIT_CWD
返回package.json
的目录
注意,$INIT_CWD 仅适用于 Linux。对于 Windows,您必须使用 %INIT_CWD%。我认为这个问题可以通过使用 npmjs.com/package/cross-env 来解决,但我自己没有尝试过【参考方案4】:
path.resolve('.')
也是一个可靠且干净的选项,因为我们几乎总是require('path')
。它将为您提供调用它的目录的绝对路径。
【讨论】:
【参考方案5】:这对我有用:
console.log(process.mainModule.filename);
【讨论】:
以上是关于运行节点 bin 脚本时确定命令行工作目录的主要内容,如果未能解决你的问题,请参考以下文章