[QUESTION] How do you run a command silently
WestleyK opened this issue · 2 comments
So, I have a test script
#!/bin/sh
echo -n "Enter your input: "
read foo
echo "You entered: ${foo}"
And then I have my go code:
package main
import (
"log"
"fmt"
"os"
"os/exec"
"time"
expect "github.com/Netflix/go-expect"
)
func main() {
c, err := expect.NewConsole(expect.WithStdout(os.Stdout))
if err != nil {
log.Fatal(err)
}
defer c.Close()
cmd := exec.Command("./sh.sh")
cmd.Stdin = c.Tty()
cmd.Stdout = c.Tty()
cmd.Stderr = c.Tty()
go func() {
c.ExpectEOF()
}()
err = cmd.Start()
if err != nil {
log.Fatal(err)
}
time.Sleep(time.Second)
c.Send("hello world\n")
time.Sleep(time.Second)
err = cmd.Wait()
if err != nil {
log.Fatal(err)
}
fmt.Println("done")
}
And it does work when I run it:
$ go run foo.go
Enter your input: hello world
You entered: hello world
done
But can I run it silently? With no output, like:
$ go run foo.go
done
Also is the time.Sleep(time.Second)
delay necessary? That will take up a lot of time if theres a lot of commands running.
Hi @WestleyK , you can run it without sleep like so:
package main
import (
"fmt"
"log"
"os"
"os/exec"
expect "github.com/Netflix/go-expect"
)
func main() {
c, err := expect.NewConsole(expect.WithStdout(os.Stdout))
if err != nil {
log.Fatal(err)
}
defer c.Close()
cmd := exec.Command("./sh.sh")
cmd.Stdin = c.Tty()
cmd.Stdout = c.Tty()
cmd.Stderr = c.Tty()
done := make(chan struct{})
go func() {
defer close(done)
c.ExpectString("Enter your input: ")
c.SendLine("hello world")
c.ExpectEOF()
}()
err = cmd.Run()
if err != nil {
log.Fatal(err)
}
c.Tty().Close()
<-done
fmt.Println("done")
}
c.ExpectString
line unblocks when it has read the text Enter your input
and then responds with hello world
. We wait for a EOF or Tty close which I do later as c.Tty().Close()
. I setup a channel (or you can use a sync.WaitGroup
) to wait the goroutine to exit before printing done.
$ time go run .
Enter your input: hello world
You entered: hello world
done
go run . 0.22s user 0.06s system 163% cpu 0.167 total
You don't have to multiplex the output to os.Stdout
, just create the expect.NewConsole
with no arguments:
// ...
c, err := expect.NewConsole()
if err != nil {
log.Fatal(err)
}
defer c.Close()
// ...
The output then becomes:
$ go run .
done
Supper thanks! Works perfectly 👍