azizulhakim
azizulhakim

Reputation: 658

How to Pass Console Input to Subprocess from Golang

I have the following C program.

#include<stdio.h>


int main() {
    int i = 0;
    char ch;

    printf("Starting test application\n");

    for (i=0; i<10; i++) {
        ch = getchar();

        printf("character at %d = %d\n", i, ch);
    }

    return 0;
}

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.

cmd := exec.Command("/home/dodtech/go-workspace/MachineListener/Test")

cmd.Stdout = os.Stdout
err := cmd.Start()

if err == nil {
    var ctrlc [9]byte
    ctrlc[0] = 0x00
    ctrlc[1] = 0x01
    ctrlc[2] = 0x02
    ctrlc[3] = 0x03
    ctrlc[4] = 0x04
    ctrlc[5] = 0x05
    ctrlc[6] = 0x06
    ctrlc[7] = 0x07
    ctrlc[8] = 0x08
    ctrlc[9] = 0x09

    cmd.Stdin = bytes.NewReader(ctrlc[0:])
    cmd.Stdin.Read(ctrlc[0:])
}

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 .

Upvotes: 1

Views: 1536

Answers (2)

eugenioy
eugenioy

Reputation: 12393

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

Like:

subStdin, err := cmd.StdinPipe()
// check err
defer subStdin.Close()
// simply write the byte array you have to stdin
subStdin.Write(ctrlc)

// io.WriteString(subStdin, "Hello World") will check if the pipe
// is a StringWriter type and use that method, if not, then convert
// the string to a byte array and write it. In this case we know 
// 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

Upvotes: 1

Milo Christiansen
Milo Christiansen

Reputation: 3294

How about:

cmd := exec.Command("/home/dodtech/go-workspace/MachineListener/Test")

cmd.Stdin = bytes.NewReader([]byte{
    0x00,
    0x01,
    0x02,
    0x03,
    0x04,
    0x05,
    0x06,
    0x07,
    0x08,
    0x09,
})
cmd.Stdout = os.Stdout

err := cmd.Start()
if err != nil {
    // Handle error
}

That should give you what you want...

Upvotes: 1

Related Questions