如何从 node.js 应用程序运行命令行工具
Posted
技术标签:
【中文标题】如何从 node.js 应用程序运行命令行工具【英文标题】:How to run a command line tool from node.js application 【发布时间】:2018-02-03 23:02:36 【问题描述】:我的问题的标题是,因为我认为这里的答案将适用于可从 npm 安装的所有命令行实用程序。我已经看到与从 node.js 运行命令行相关的问题,但它们似乎不适用于我的情况。具体来说,我正在尝试运行一个类似于 npm 的节点命令行实用程序(在它的使用方式上,但不是它的功能),称为 tilemantle。
tilemantle 的 documentation 显示全局安装 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 而无需全局安装它?
更新
我可以使用 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
替换tilemantle,我得到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 错误的情况下运行,但它再次静默失败,只是没有预热我的磁贴服务器。
我正在使用 Node 6.11.0 运行 Windows 10 x64
【问题讨论】:
我链接的帖子有一条关于在 Windows 上运行的评论here 【参考方案1】:您似乎正试图通过运行文件而不是从命令行捕获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
运行它。
我尝试了this post 中的许多其他选项,但只能让上述选项与其他输出一起打印进度。希望这会有所帮助!
【讨论】:
【参考方案2】:您可以在本地安装任何可执行文件,然后使用 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 文件的路径。
当然,这一切都假定节点在您的路径中,以便系统可以找到它。如果它不在您的路径中,那么您还必须使用节点可执行文件的完整路径。
【讨论】:
【参考方案3】:许多命令行实用程序都带有“程序化”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"
您现在可以从项目中的终端运行npm test
作为tldr curl
的别名。
根据this post,您可以使用 global-npm 包从您的代码中运行 npm 脚本:
const npm = require('global-npm')
npm.load(, (err) =>
if (err) throw err
npm.commands.run(['test'])
)
瞧,您现在可以以编程方式(ish)运行本地安装的 CLI,即使它没有为此提供 API。
【讨论】:
以上是关于如何从 node.js 应用程序运行命令行工具的主要内容,如果未能解决你的问题,请参考以下文章