How to Pass Console Input to Subprocess from Golang

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

How to Pass Console Input to Subprocess from Golang

问题

我有以下的C程序。

  1. #include<stdio.h>
  2. int main() {
  3. int i = 0;
  4. char ch;
  5. printf("Starting test application\n");
  6. for (i=0; i<10; i++) {
  7. ch = getchar();
  8. printf("character at %d = %d\n", i, ch);
  9. }
  10. return 0;
  11. }

我想从Go语言中将这个程序作为子进程运行。在我的Go代码中,我有一个byte数组,我希望将其用作输入传递给我的C程序。我尝试了以下方法,但没有成功。

  1. cmd := exec.Command("/home/dodtech/go-workspace/MachineListener/Test")
  2. cmd.Stdout = os.Stdout
  3. err := cmd.Start()
  4. if err == nil {
  5. var ctrlc [9]byte
  6. ctrlc[0] = 0x00
  7. ctrlc[1] = 0x01
  8. ctrlc[2] = 0x02
  9. ctrlc[3] = 0x03
  10. ctrlc[4] = 0x04
  11. ctrlc[5] = 0x05
  12. ctrlc[6] = 0x06
  13. ctrlc[7] = 0x07
  14. ctrlc[8] = 0x08
  15. ctrlc[9] = 0x09
  16. cmd.Stdin = bytes.NewReader(ctrlc[0:])
  17. cmd.Stdin.Read(ctrlc[0:])
  18. }

需要注意的是,上述两个程序只是测试程序,它们只代表我想要实现的目标。它们并不旨在高效,并且没有按照编程准则编写(例如,字节数组的创建方式)。如果我能解决这个小问题,我就能将其移植到我的实际软件代码中。如果有人能指导我如何做到这一点,我将不胜感激。

英文:

I have the following C program.

  1. #include&lt;stdio.h&gt;
  2. int main() {
  3. int i = 0;
  4. char ch;
  5. printf(&quot;Starting test application\n&quot;);
  6. for (i=0; i&lt;10; i++) {
  7. ch = getchar();
  8. printf(&quot;character at %d = %d\n&quot;, i, ch);
  9. }
  10. return 0;
  11. }

I want to run this program as a sub-process from Go language. In my Go code, I have a byte array which I want to be used as input to my C program. I tried following approach and it did not work.

  1. cmd := exec.Command(&quot;/home/dodtech/go-workspace/MachineListener/Test&quot;)
  2. cmd.Stdout = os.Stdout
  3. err := cmd.Start()
  4. if err == nil {
  5. var ctrlc [9]byte
  6. ctrlc[0] = 0x00
  7. ctrlc[1] = 0x01
  8. ctrlc[2] = 0x02
  9. ctrlc[3] = 0x03
  10. ctrlc[4] = 0x04
  11. ctrlc[5] = 0x05
  12. ctrlc[6] = 0x06
  13. ctrlc[7] = 0x07
  14. ctrlc[8] = 0x08
  15. ctrlc[9] = 0x09
  16. cmd.Stdin = bytes.NewReader(ctrlc[0:])
  17. cmd.Stdin.Read(ctrlc[0:])
  18. }

To be noted, both of the above program is just a test program and they only represent what I want to achieve. They are not meant to be efficient and was not written according to programming guidelines(for example the way byte array was created). If I can solve my problem for this small case, I will be able to port it to my actual software code. I would appreciate if anyone can guide me how I can do this .

答案1

得分: 1

如果你想写入子进程的标准输入,你应该使用StdinPipe

像这样:

  1. subStdin, err := cmd.StdinPipe()
  2. // 检查错误
  3. defer subStdin.Close()
  4. // 简单地将字节数组写入标准输入
  5. subStdin.Write(ctrlc)
  6. // io.WriteString(subStdin, &quot;Hello World&quot;) 会检查管道是否是StringWriter类型,并使用该方法,如果不是,则将字符串转换为字节数组并写入。在这种情况下,我们知道该管道没有自己的写入字符串的方法。

请参阅完整示例的文档:

https://golang.org/pkg/os/exec/#Cmd.StdinPipe

英文:

If you want to write to the sub-process standard input, you should use StdinPipe.

Like:

  1. subStdin, err := cmd.StdinPipe()
  2. // check err
  3. defer subStdin.Close()
  4. // simply write the byte array you have to stdin
  5. subStdin.Write(ctrlc)
  6. // io.WriteString(subStdin, &quot;Hello World&quot;) will check if the pipe
  7. // is a StringWriter type and use that method, if not, then convert
  8. // the string to a byte array and write it. In this case we know
  9. // that the pipe does not have a method for writing strings to itself.

See the docs for a complete example:

https://golang.org/pkg/os/exec/#Cmd.StdinPipe

答案2

得分: 1

如何:

  1. cmd := exec.Command("/home/dodtech/go-workspace/MachineListener/Test")
  2. cmd.Stdin = bytes.NewReader([]byte{
  3. 0x00,
  4. 0x01,
  5. 0x02,
  6. 0x03,
  7. 0x04,
  8. 0x05,
  9. 0x06,
  10. 0x07,
  11. 0x08,
  12. 0x09,
  13. })
  14. cmd.Stdout = os.Stdout
  15. err := cmd.Start()
  16. if err != nil {
  17. // 处理错误
  18. }

这样应该可以得到你想要的结果...

英文:

How about:

  1. cmd := exec.Command(&quot;/home/dodtech/go-workspace/MachineListener/Test&quot;)
  2. cmd.Stdin = bytes.NewReader([]byte{
  3. 0x00,
  4. 0x01,
  5. 0x02,
  6. 0x03,
  7. 0x04,
  8. 0x05,
  9. 0x06,
  10. 0x07,
  11. 0x08,
  12. 0x09,
  13. })
  14. cmd.Stdout = os.Stdout
  15. err := cmd.Start()
  16. if err != nil {
  17. // Handle error
  18. }

That should give you what you want...

huangapple
  • 本文由 发表于 2017年7月29日 01:44:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/45379494.html
匿名

发表评论

匿名网友

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

确定