Иди сканируй буфер зависает иногда - PullRequest
1 голос
/ 11 ноября 2019

Я использую следующий код, который работает нормально, однако в некоторых случаях процесс зависает, и я не вижу никакого вывода. Например, этот код работает npm install или mvn clean install, и большую часть времени он работает хорошо, но иногда он зависает, и вы не получаете никакого вывода

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {
    scanout := bufio.NewScanner(stdout)
    scanerr := bufio.NewScanner(stderr)

    scanout.Split(bufio.ScanRunes)
    for scanout.Scan() {
        fmt.Print(scanout.Text())
    }

    scanerr.Split(bufio.ScanRunes)
    for scanerr.Scan() {
        fmt.Print(scanerr.Text())
    }
    return scanout, scanerr
}

Теперь, если я изменю порядок следующим образом (сначала ошибка иstdout second) Я получаю некоторые сообщения об ошибках, когда команда зависает, однако я не вижу выходных данных в режиме онлайн, когда вы запускаете команду, вы видите какой-то вывод, а когда закончите, вы видите все остальное. вы можете ждать вывода в течение 2 минут и более, и вы получите длинный вывод сразу в конце процесса.

Как я могу исправить то, что смогу получать выходные данные онлайн, а также получать некоторую обратную связь, когда процесс зависает?

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {
    scanout := bufio.NewScanner(stdout)
    scanerr := bufio.NewScanner(stderr)

    scanout.Split(bufio.ScanRunes)
    for scanout.Scan() {
        fmt.Print(scanout.Text())
    }
    scanerr.Split(bufio.ScanRunes)
    for scanerr.Scan() {
        fmt.Print(scanerr.Text())
    }


    }
    return scanout, scanerr
}

update

Должно ли это быть так?

func exec(stdout io.Reader, stderr io.Reader) (*bufio.Scanner, *bufio.Scanner) {

scanout := bufio.NewScanner(stdout)
scanout.Split(bufio.ScanRunes)
go func() {
    for scanout.Scan() {
        fmt.Print(scanout.Text())
     }
}()

go func() {
scanerr.Split(bufio.ScanRunes)
        for scanerr.Scan() {
            fmt.Print(scanerr.Text())
        }
}()

}

1 Ответ

2 голосов
/ 11 ноября 2019

В первом случае вы читаете из стандартного потока процесса до его завершения. Затем вы читаете из stderr. Во втором случае вы сначала читаете из err, а затем из out. Вы должны читать из них обоих. Либо используйте Cmd.CombinedOutput, который возвратит их обоих, либо запустите две процедуры, одну для чтения из stdin и одну для чтения из stderr, пока потоки не закроются.

scanout := bufio.NewScanner(stdout)
scanout.Split(bufio.ScanRunes)
go func() {
    for scanout.Scan() {
        fmt.Print(scanout.Text())
     }
}()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...