Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

doesn't take repeated input from stdin

I have a contrived program where the goal is to echo text on stdin (as many times as you want), and exit after 10 sec. Code is below:

package main

import (
    "bufio"
    "fmt"
    "os"
    "time"
)

func main() {
    input := make(chan string)
    abort := make(chan bool)

    // exit after 10 sec
    go func() {
        time.Sleep(10 * time.Second)
        abort <- true
    }()

    go func() {
        cmd := bufio.NewScanner(os.Stdin)
        for cmd.Scan() {
            input <- "<- " + cmd.Text()
        }
    }()

    select {
    case <-abort:
        fmt.Println("exiting")
        return
    case cmd := <-input:
        fmt.Println(cmd)
    }
}

The problem is when I enter the first line of text, it is echoed back to stdout and program exits. I want to enter as many commands as I want for 10 seconds.

What am I doing wrong ?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The abort channel is being closed after 10 seconds which makes the first select case (<-abort) being triggered and the program exiting. Heres what i got

func main() {
input := make(chan string)
abort := make(chan bool)

// exit after 10 sec
go func() {
    time.Sleep(10 * time.Second)
    close(abort) // Close the channel after 10 seconds
}()

go func() {
    cmd := bufio.NewScanner(os.Stdin)
    for cmd.Scan() {
        input <- "<- " + cmd.Text()
    }
}()

for {
    select {
    case <-abort:
        fmt.Println("closing connection")
        return
    case cmd := <-input:
        fmt.Println(cmd)
    }
}
}'

I replaced the outside select statement with an infinite loop using ‘for’
After the 10 second timeout I’m using the close(abort) statement to close the abort’s channel. This will tell the select statement that the timeout has occurred and it should proceed to the first case (<-abort) when the channel is closed. I had a sezier typing that so i hope you get it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading