我正在寻找一种同时处理stdout和stderr作为一个流的方法。 对于stdout,我可以使用:
cmd := exec.Command(command, flags...)
var wg sync.WaitGroup
stdout, err := cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("RunCommand: cmd.StdoutPipe(): %v", err)
}
if err := cmd.Start(); err != nil {
return fmt.Errorf("RunCommand: cmd.Start(): %v", err)
}
scanner := bufio.NewScanner(stdout)
scanner.Split(ScanLinesR)
wg.Add(1)
go func() {
for scanner.Scan() {
text := scanner.Text()
if strings.TrimSpace(text) != "" {
DoWhateverYouNeedWithText(text)
}
}
wg.Done()
}()
wg.Wait()
但是我如何将stderr添加到相同的代码中?
答案 0 :(得分:2)
如上所述,评论员建议我增加2个goroutine(一个用于stderr,一个用于关闭频道)。
--- switch_loadable_module.c 2017-07-13 20:07:30.000000000 +0800
+++ freeswitch-1.6.19/src/switch_loadable_module.c 2017-09-29 17:23:10.000000000 +0800
@@ -1875,15 +1875,6 @@
if (!autoload) return SWITCH_STATUS_SUCCESS;
- switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_FALSE, &err);
- switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_FALSE, &err);
- switch_loadable_module_load_module("", "CORE_SPEEX_MODULE", SWITCH_FALSE, &err);
-#ifdef SWITCH_HAVE_YUV
-#ifdef SWITCH_HAVE_VPX
- switch_loadable_module_load_module("", "CORE_VPX_MODULE", SWITCH_FALSE, &err);
-#endif
-#endif
-
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_xml_t mods, ld;
if ((mods = switch_xml_child(cfg, "modules"))) {
@@ -1980,6 +1971,15 @@
apr_dir_close(module_dir_handle);
}
+ switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_FALSE, &err);
+ switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_FALSE, &err);
+ switch_loadable_module_load_module("", "CORE_SPEEX_MODULE", SWITCH_FALSE, &err);
+#ifdef SWITCH_HAVE_YUV
+#ifdef SWITCH_HAVE_VPX
+ switch_loadable_module_load_module("", "CORE_VPX_MODULE", SWITCH_FALSE, &err);
+#endif
+#endif
+
switch_loadable_module_runtime();
memset(&chat_globals, 0, sizeof(chat_globals));
答案 1 :(得分:0)
// child.go
func main() {
fmt.Fprintln(os.Stdout, "Child started.")
time.Sleep(time.Second * 1)
fmt.Println("Tick...")
time.Sleep(time.Second * 1)
fmt.Println("Tick...")
time.Sleep(time.Second * 1)
fmt.Println("Tick...")
time.Sleep(time.Second * 2)
fmt.Println("Child ended.")
}
// childerr.go
func main() {
fmt.Fprintln(os.Stdout, "Child started.")
time.Sleep(time.Second * 1)
fmt.Fprintln(os.Stdout, "Tick...")
time.Sleep(time.Second * 1)
fmt.Fprintln(os.Stdout, "Tick...")
time.Sleep(time.Second * 1)
fmt.Fprintln(os.Stdout, "Tick...")
time.Sleep(time.Second * 2)
panic("testing")
fmt.Fprintln(os.Stdout, "Child ended.")
}
func executeCommand(output chan<- string, err chan<- error, start chan interface{}, cmd *exec.Cmd) {
defer close(start)
stdout, e := cmd.StdoutPipe()
if e != nil {
log.Println("Error starting Cmd: ", e)
err <- e
return
}
cmd.Stderr = cmd.Stdout
<-start
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
output <- scanner.Text()
}
}
func run(cmd *exec.Cmd) {
start := make(chan interface{})
output := make(chan string)
errChan := make(chan error)
defer close(output)
defer close(errChan)
go executeCommand(output, errChan, start, cmd)
start <- nil
if e := cmd.Start(); e != nil {
log.Println("Error starting Cmd: ", e)
}
for {
select {
case b := <-output:
fmt.Println(b)
case e := <-errChan:
fmt.Println("ERR EXECUTING COMMAND->", e)
return
case <-start:
fmt.Println("COMPLETED")
return
}
}
}
使用child或childerr创建长时间运行的样本。