如何从Node.js应用程序运行命令行工具



我问题的标题是如何从节点.js应用程序运行命令行工具,因为我认为这里的答案将适用于所有可从 npm 安装的命令行实用程序。我已经看到了与从node.js运行命令行相关的问题,但它们似乎不适用于我的情况。具体来说,我正在尝试运行一个类似于 npm 的节点命令行实用程序(在如何使用它的方式上,但不是它的功能),称为 tilemantle。

Tilemantle的文档显示了全局安装Tilemantle并从命令行运行程序。

我想做的是使用npm install tilemantle --save在本地安装 tilemantle 作为 npm 项目的一部分,然后从我的项目内部运行 tilemantle。

我已经尝试过'tilemantle = require('tilemantle'),但是tilemantle项目中的index.js文件是空的,所以我认为这对任何事情都没有帮助。

我尝试了该项目node-cmd

const cmd = require('node-cmd');
cmd.run('./node_modules/tilemantle/bin/tilemantle', 'http://localhost:5000/layer/{z}/{x}/{y}/tile.png', '-z 0-11', '--delay=100ms', '--point=37.819895,-122.478674', '--buffer=100mi'

这不会引发任何错误,但也不起作用。

我还尝试了子进程

const child_process = require('child_process');
child_process.exec('./node_modules/tilemantle/bin/tilemantle', 'http://localhost:5000/layer/{z}/{x}/{y}/tile.png, -z 0-11 --delay=100ms --point=37.819895,-122.478674 --buffer=100mi'

这也不会引发任何错误,但也不起作用。

有没有办法让它工作,这样我就可以从我的程序内部运行tilemantle,而不需要全局安装它?

更新

我可以让瓦幔从我的终端运行

node './node_modules/tilemantle/bin/tilemantle', 'http://localhost:5000/layer/{z}/{x}/{y}/tile.png', '--delay=100ms', '--point=37.819895,-122.478674', '--buffer=100mi', '-z 0-11'

如果我按照jkwok的建议运行以下内容

child_process.spawn('tilemantle', ['http://myhost.com/{z}/{x}/{y}.png',
'--point=44.523333,-109.057222', '--buffer=12mi', '-z', '10-14'],
{ stdio: 'inherit' });

我正在spawn tilemantle ENOENT,如果我用./node_modules/tilemantle/bin/tilemantle.js替换瓷砖,我会得到spawn UNKNOWN

根据jfriend00的回答,听起来我需要实际生成节点,所以我尝试了以下内容

child_process.spawn('node', ['./node_modules/tilemantle/bin/tilemantle.js', 'http://myhost.com/{z}/{x}/{y}.png', '--point=44.523333,-109.057222', '--buffer=12mi', '-z', '10-14'], { stdio: 'inherit' });

这给了我错误spawn node ENOENT这似乎很奇怪,因为我可以从我的终端运行它,并且我检查了我的路径变量C:Program Filesnodejs并且它在我的路径上。

只是为了检查我尝试使用节点的完整路径运行以下内容。

child_process.spawn('c:/program files/nodejs/node.exe', ['./node_modules/tilemantle/bin/tilemantle.js', 'http://myhost.com/{z}/{x}/{y}.png', '--point=44.523333,-109.057222', '--buffer=12mi', '-z', '10-14'], { stdio: 'inherit' });

在没有 ENOENT 错误的情况下运行,但它再次静默失败,只是没有预热我的磁贴服务器。

我正在运行带有节点 10 的 Windows 64 x6.11.0

您可以在本地安装任何可执行文件,然后使用 child_process 运行它。 为此,您只需找出可执行文件的确切路径,并将该路径传递给child_process.exec()child_process.spawn()调用。

看起来你最终想要运行的是一个命令行,它执行:

node <somepath>/tilemantle.js

当您在Windows上安装时,如果您运行以下命令,它将为您完成大部分工作:

node_modules.bintilemantle.cmd

如果你想直接运行js文件(例如在其他平台上),那么你需要运行:

node node_modules/tilemantle/bin/tilemantle.js

请注意,对于child_process,您必须指定实际的可执行文件,在这种情况下是"节点"本身,然后是您希望运行的 js 文件的路径。

当然,这一切都假设节点在您的路径中,以便系统可以找到它。 如果它不在您的路径中,那么您还必须使用节点可执行文件的完整路径。

看起来您正在尝试通过运行文件而不是从命令行捕获tilemantle的输出。如果是这样,我做了以下操作并使其工作。

像您一样将tilemantle和本地child_process安装到新的 npm 项目中,并将以下内容添加到该项目的文件中。

//  test.js file
var spawn = require('child_process').spawn;
spawn('tilemantle', ['http://myhost.com/{z}/{x}/{y}.png', '--
point=44.523333,-109.057222', '--buffer=12mi', '-z', '10-14'], { stdio: 'inherit' });

使用项目内的node test.js运行它。

我在这篇文章中尝试了一堆其他选项,但只能让上面的选项打印进度以及其他输出。希望这有帮助!

许多命令行实用程序都带有"编程"API。不幸的是,tilemantle没有,这就是为什么您无法在代码中require该模块的原因。

但是,您可以从 npm 脚本轻松访问本地安装的 CLI 版本。我对tilemantle一无所知,所以我将使用tldr命令行工具提供一个示例。在你的包.json中:

{
"name": "my-lib",
"version": "1.0.0",
"scripts": {
"test": "tldr curl"
},
"dependencies": {
"tldr": "^2.0.1"
}
}

现在,您可以从项目中的终端运行npm test作为tldr curl的别名。

根据这篇文章,您可以使用 global-npm 包从您的代码运行 npm 脚本:

const npm = require('global-npm')
npm.load({}, (err) => {
if (err) throw err
npm.commands.run(['test'])
})

瞧,您现在可以以编程方式(ish)运行本地安装的 CLI,即使它没有为此提供 API。

最新更新