What is the best way to save ssh output into a struct in golang?

huangapple go评论68阅读模式
英文:

What is the best way to save ssh output into a struct in golang?

问题

我正在尝试将在其他机器上通过SSH运行的一些命令的输出保存到一个结构体中。我使用了CombinedOutput来保存输出。类似这样的代码:

...
combo, err := session.CombinedOutput("hostname;pwd")
outputResult = string(combo)
...

它给我返回了两行输出。我想将这些行保存到下面的结构体中:

type Result struct {
	Hostname string `json:"hostname"`
	PWD      string `json:"pwd"`
}

有什么最好(且简单)的方法可以做到这一点吗?谢谢。

英文:

I'm trying to save output of running some commands on other machine with SSH, into a struct.
I used CombinedOutput to save the output. Something like this:

...
combo, err := session.CombinedOutput("hostname;pwd")
outputResult = string(combo)
...

It gives me a 2-line output. I want to save these lines into the below struct:

type Result struct {
	Hostname string `json:"hostname"`
	PWD      string `json:"pwd"`
}

What is the best (and easy) way to do that? Thanks.

答案1

得分: 0

这是要翻译的内容:

> 它给我输出了两行。我想把这两行保存到下面的结构体中。

你的问题与SSH没有任何关系。你有一个表示命令输出的[]byte,你想将它分割成两个字符串。

strings.SplitN 是解决这个问题的完美方法。你将原始字符串(需要将[]byte转换为字符串)、分隔符(在你的情况下是\n)和要返回的字符串的最大数量传递给它。对于我们来说,我们最多要返回2个字符串。为什么会有多个\n呢?pwd返回一个目录,目录的名称中可能包含换行符,尽管在实际情况下很少出现。

out := []byte("myhost\n/dir")
fmt.Println(string(out))
strs := strings.SplitN(string(out), "\n", 2)
res := Result{Hostname: strs[0], PWD: strs[1]}
out := []byte("myhost\n/dir")
fmt.Println(string(out))
strs := strings.SplitN(string(out), "\n", 2)
res := Result{Hostname: strs[0], PWD: strs[1]}

https://go.dev/play/p/5ENSgAPg3ER

> go > combo, err := session.CombinedOutput("hostname;pwd") >

请记住,这也会包括stderr,而不仅仅是stdout。我想不出任何情况下这两个命令会生成任何stderr输出,但请记住,你没有区分这两者。希望你正在检查err的结果,如果不是nil,则不使用命令的结果。这样可以保护你免受stdout和stderr组合的意外结果的影响。如果stderr对你来说永远不相关,你可能想使用ssh.Session.Output

英文:

> It gives me a 2-line output. I want to save these lines into the below struct

Your question really has nothing to do with SSH. You have a []byte that represents the output of your commands. You want to split it into two strings.

strings.SplitN is the perfect solution for this. You pass it the original string (to which the []byte must be converted), the separator (\n in your case), and the maximum number of strings to return. For us, we want at most 2 strings. How could there be more than one \n? pwd returns a directory, and directories can have newlines in their names, though they very rarely do in practice.

	out := []byte("myhost\n/dir")
	fmt.Println(string(out))
	strs := strings.SplitN(string(out), "\n", 2)
	res := Result{Hostname: strs[0], PWD: strs[1]}
	out := []byte("myhost\n/dir")
	fmt.Println(string(out))
	strs := strings.SplitN(string(out), "\n", 2)
	res := Result{Hostname: strs[0], PWD: strs[1]}

https://go.dev/play/p/5ENSgAPg3ER

>
> combo, err := session.CombinedOutput("hostname;pwd")
>

Remember that this will also include the stderr in addition to the stdout. I can't think of a situation where either command would generate any output to stderr, but keep in mind that you're not distinguishing between the two. Hopefully you're checking the result of err and if not nil, not consuming the results of the command. That should protect you from unanticipated results from the combination of stdout and stderr. If stderr is never relevant for you, you might want to use ssh.Session.Output instead

huangapple
  • 本文由 发表于 2022年3月13日 23:07:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/71458034.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定