[英]Go exec.Command pipe output into another powershell
我是 Go 的新手,我遇到了以下问题。 我需要使用 os.exec 与 powershell 交互并捕获 output 中的每个命令/管道。
例如,我有以下命令
powershell /C cat somefile.md | Select-String -Pattern someinput
我需要第一个命令的 output
powershell /C cat somefile.md
和 pipe 的 output
powershell /C Select-String -Pattern someinput
下面的代码在 linux 和 cmd 在 Windows 上工作正常,我必须使用 Z2F2D399F0EA8847859FEZ51B34...
编辑:经过进一步调查,我得出结论,无论出于何种原因, Select-String
和其他 powershell 特定命令都不能通过管道传输。 是因为 powershell 需要 PSObject 作为输入吗?
那是我现在乱七八糟的代码:
func executeCmds{
//save all exec.Commands in one array (I've no clue how many cmds there are later)
var cmdList []exec.Cmds
cmdList = append(cmdList, *exec.Command("powershell", "/C", "cat somefile.md"))
//*****EDIT*****//
// not working $Input is missing
cmdList = append(cmdList, *exec.Command("powershell", "/C", "Select-String -Pattern someinput"))
// working command $Input is important
cmdList = append(cmdList, exec.Command("powershell", "/C", "$Input | Select-String -Pattern someinput"))
// this is performance wise NOT an option!
// cmdList = append(cmdList, *exec.Command("powershell", "/C", "cat somefile.md | Select-String -Pattern someinput"))
// save the latest stdout into tmp to stdin the next command (works fine on linux and cmd.exe)
var tmp []byte
for i, s := range cmdList {
if i > 0 {
s.Stdin = strings.NewReader(string(tmp)) //this does not work, powershell somehow can't use Stdin
}
stdout, err := s.CombinedOutput()
tmp = stdout
if err != nil {
o := fmt.Sprint(err) + ": " + string(stdout)
err = errors.New(o)
panic(err)
break
}
// Print the output
fmt.Println(string(stdout))
}
}
您不需要为此使用 PowerShell,您可以直接使用 Go :
package main
import "golang.org/x/sys/windows/registry"
func main() {
a, e := registry.CURRENT_USER.ReadSubKeyNames(0)
if e != nil {
panic(e)
}
for _, s := range a {
println(s)
}
}
如果您需要通过 go 应用程序传递数据,那么您可以执行以下操作(我不确定这将如何提高使用 powershell 管道的性能):
package main
import (
"fmt"
"io"
"os/exec"
)
func main() {
// save all exec.Commands in one array (I've no clue how many cmds there are later)
var cmdList []*exec.Cmd
cmdList = append(cmdList, exec.Command("powershell", "/C", "cat somefile.md"))
cmdList = append(cmdList, exec.Command("powershell", "/C", "$Input | Select-String -Pattern someinput"))
var tmp []byte
for i, s := range cmdList {
if i > 0 { // Send the output of the previous command into the next command
input, err := s.StdinPipe()
if err != nil {
panic(err)
}
go func(w io.WriteCloser, data []byte) {
w.Write(data) // Should really check for errors here
w.Close()
}(input, tmp)
}
var err error
tmp, err = s.CombinedOutput() // As you are taking standard error here too you should check for errors
if err != nil {
panic(err)
}
}
// Print the final output
fmt.Println(string(tmp))
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.