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

问题描述:

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

tilemantle's documentation显示全局安装tilemantle并从命令行运行程序。

我想要做的是在本地安装tilemantle作为npm项目的一部分,使用npm install tilemantle --save,然后从我的项目中运行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,而不需要全局安装它?

更新

我可以得到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's answer这听起来像我需要实际上是产卵节点,所以我尝试以下

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 Files\nodejs在我的道路上。

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

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错误,但它再次被静默失败,只是没有热身我的瓷砖服务器。

我运行Windows 10的x64与节点6.11.0

+0

我链接到的帖子有关于在Windows上运行的评论[这里](https://*.com/questions/17516772/using-nodejss-spawn-causes-unknown-option-and-error-spawn-enoent -ERR/17537559#17537559) – jkwok

很多命令行工具来使用 “程序” API。不幸的是,tilemantle没有,这就是为什么你无法在你的代码中使用require这个模块。

但是,您可以轻松地从npm脚本访问本地安装的CLI版本。我对tilemantle没有任何了解,所以我将使用tldr命令行工具提供示例。在你的package.json:

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

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

this post,您可以使用全球公共管理包从你的代码运行NPM脚本:

const npm = require('global-npm') 

npm.load({}, (err) => { 
    if (err) throw err 

    npm.commands.run(['test']) 
}) 

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

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

是什么样子,你最终要运行一个命令行的作用:

node <somepath>/tilemantle.js 

当你在Windows上安装,它会做的大多数是你,如果你运行:

node_modules\.bin\tilemantle.cmd 

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

node node_modules/tilemantle/bin/tilemantle.js 

请注意,使用child_process时,必须指定实际的可执行文件,在本例中为“节点”本身,然后指定要运行的js文件的路径。

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

它看起来像你试图从运行一个文件,而不是从命令行捕获tilemantle的输出。如果是这样,我做了以下工作。

安装tilemantlechild_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运行它。

我试了一堆this post其他选项,但只能得到上面的一个与其他输出一起打印进度。希望这可以帮助!