从 golang 执行 nodejs 脚本的最佳方式是 returns 一个字符串,然后将该字符串传回 golang 变量?
What's the optimal way to execute a nodejs script from golang, that returns a string, and then communicate that string back to a golang variable?
我目前在 golang 方面使用 os/exec
和 Stdout
,在 nodejs 方面使用 console.log("string")
。
基本上我需要生成一个字符串,但只能在 nodejs 中生成,但我的大部分代码都在 golang 中,所以我试图让我的代码中的这个小问题尽可能无缝、安全和可靠可能,我对将程序中如此重要的部分放在 "console.log" 上并从 shell 输出中读取感到有点不安。
简而言之:我想知道在我的节点和 go 代码然后 console.log + shell 输出之间是否存在更好和更标准的通信线路,或者这是否足够优化?
哦,我程序的这个特定部分的功能是获取降价文本文件并使用 markdown-it.
将其转换为 HTML
一些想法:
- 通过 HTTP 通信(将 data/string 发送到 golang http 侦听器)
- 通过文件系统进行通信(将字符串写入临时文件,用golang读取)
- 通过"something similiar to HTTP but specific to local application data sharing"
沟通
P.S.
我不能使用 otto,因为那里没有 markdown-运行。
实际代码:
parser.go
package main
import (
"os"
"os/exec"
"fmt"
"bytes"
)
func main() {
cmd := "node"
args := []string{"parser.js", "/home/user1/dev/current/wikis/Bob's Pain/markup/index.md"}
process := exec.Command(cmd, args...)
stdin, err := process.StdinPipe()
if err != nil {
fmt.Println(err)
}
defer stdin.Close()
buf := new(bytes.Buffer) // THIS STORES THE NODEJS OUTPUT
process.Stdout = buf
process.Stderr = os.Stderr
if err = process.Start(); err != nil {
fmt.Println("An error occured: ", err)
}
process.Wait()
fmt.Println("Generated string:", buf)
}
parser.js
var md = require('markdown-it')();
var yaml = require('js-yaml');
var fs = require('fs');
if (process.argv.length < 3) {
console.log('Usage: node ' + process.argv[1] + ' FILENAME');
process.exit(1);
}
var filename = process.argv[2];
fs.readFile(filename, 'utf8', function(err, data) {
if (err) {
throw err;
}
parse(data)
});
function parse(data) {
data = data.split("---")
yamlData = data[1];
markData = data[2];
y = yamlProcess(yamlData);
markData = "# "+y.title+"\n\n"+markData
html = markdownToHTML(markData);
console.log(html) // SEND THE DATA BACK TO GOLANG
}
function yamlProcess(data) {
try {
var doc = yaml.safeLoad(data);
return doc;
} catch (e) {
console.log(e);
return {};
}
}
function markdownToHTML(data) {
return md.render(data);
}
我用两种方法都达到了类似的要求。
对于构建管道扩展,我会编写一个 Python 脚本,该脚本从命令行获取参数并将结果输出到标准输出。这是一个简单的界面,用于 "run once"、"everything succeeds otherwise fail fast" 用法。如果您的情况相同,我会保持原样实施。
对于 Web 应用程序,我有 Java 服务用于特定功能(在我的例子中,Natty 来自自然语言字符串的日期识别)。这样做的好处是应用程序在调用时已经 "warmed up",并且肯定会更快地响应而不是每次请求进入时都启动。随着时间的推移,使用 rest 接口可能会显示出更多好处 -例如更简单的客户端实现、监控、部署选项、切换实现而不改变客户端等。只是这种方式更常规。
使用 os/exec 执行此操作的最简单方法:
command := "node parser.js /path/to/some/file.md"
parts := strings.Fields(command)
data, err := exec.Command(parts[0], parts[1:]...).Output()
if err != nil {
panic(err)
}
output := string(data)
"output" 是从您的 NodeJS 脚本打印的数据。 "command" 是字符串形式的任何命令。
我目前在 golang 方面使用 os/exec
和 Stdout
,在 nodejs 方面使用 console.log("string")
。
基本上我需要生成一个字符串,但只能在 nodejs 中生成,但我的大部分代码都在 golang 中,所以我试图让我的代码中的这个小问题尽可能无缝、安全和可靠可能,我对将程序中如此重要的部分放在 "console.log" 上并从 shell 输出中读取感到有点不安。
简而言之:我想知道在我的节点和 go 代码然后 console.log + shell 输出之间是否存在更好和更标准的通信线路,或者这是否足够优化?
哦,我程序的这个特定部分的功能是获取降价文本文件并使用 markdown-it.
将其转换为 HTML一些想法:
- 通过 HTTP 通信(将 data/string 发送到 golang http 侦听器)
- 通过文件系统进行通信(将字符串写入临时文件,用golang读取)
- 通过"something similiar to HTTP but specific to local application data sharing" 沟通
P.S.
我不能使用 otto,因为那里没有 markdown-运行。
实际代码:
parser.go
package main
import (
"os"
"os/exec"
"fmt"
"bytes"
)
func main() {
cmd := "node"
args := []string{"parser.js", "/home/user1/dev/current/wikis/Bob's Pain/markup/index.md"}
process := exec.Command(cmd, args...)
stdin, err := process.StdinPipe()
if err != nil {
fmt.Println(err)
}
defer stdin.Close()
buf := new(bytes.Buffer) // THIS STORES THE NODEJS OUTPUT
process.Stdout = buf
process.Stderr = os.Stderr
if err = process.Start(); err != nil {
fmt.Println("An error occured: ", err)
}
process.Wait()
fmt.Println("Generated string:", buf)
}
parser.js
var md = require('markdown-it')();
var yaml = require('js-yaml');
var fs = require('fs');
if (process.argv.length < 3) {
console.log('Usage: node ' + process.argv[1] + ' FILENAME');
process.exit(1);
}
var filename = process.argv[2];
fs.readFile(filename, 'utf8', function(err, data) {
if (err) {
throw err;
}
parse(data)
});
function parse(data) {
data = data.split("---")
yamlData = data[1];
markData = data[2];
y = yamlProcess(yamlData);
markData = "# "+y.title+"\n\n"+markData
html = markdownToHTML(markData);
console.log(html) // SEND THE DATA BACK TO GOLANG
}
function yamlProcess(data) {
try {
var doc = yaml.safeLoad(data);
return doc;
} catch (e) {
console.log(e);
return {};
}
}
function markdownToHTML(data) {
return md.render(data);
}
我用两种方法都达到了类似的要求。
对于构建管道扩展,我会编写一个 Python 脚本,该脚本从命令行获取参数并将结果输出到标准输出。这是一个简单的界面,用于 "run once"、"everything succeeds otherwise fail fast" 用法。如果您的情况相同,我会保持原样实施。
对于 Web 应用程序,我有 Java 服务用于特定功能(在我的例子中,Natty 来自自然语言字符串的日期识别)。这样做的好处是应用程序在调用时已经 "warmed up",并且肯定会更快地响应而不是每次请求进入时都启动。随着时间的推移,使用 rest 接口可能会显示出更多好处 -例如更简单的客户端实现、监控、部署选项、切换实现而不改变客户端等。只是这种方式更常规。
使用 os/exec 执行此操作的最简单方法:
command := "node parser.js /path/to/some/file.md"
parts := strings.Fields(command)
data, err := exec.Command(parts[0], parts[1:]...).Output()
if err != nil {
panic(err)
}
output := string(data)
"output" 是从您的 NodeJS 脚本打印的数据。 "command" 是字符串形式的任何命令。