亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

獲取 os.exec 的輸出以顯示執行命令的進度

獲取 os.exec 的輸出以顯示執行命令的進度

Go
蕭十郎 2022-08-01 15:18:19
我有一個如下函數來執行命令并向stdout(終端)顯示輸出:package main// https://blog.kowalczyk.info/article/wOYk/advanced-command-execution-in-go-with-osexec.htmlimport (    "bytes"    "io"    "fmt"    "log"    "os"    "os/exec")func main() {    cmd := exec.Command("./test.sh")    var stdoutBuf, stderrBuf bytes.Buffer    cmd.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)    cmd.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)    err := cmd.Run()    if err != nil {        log.Fatalf("cmd.Run() failed with %s\n", err)    }    outStr, errStr := string(stdoutBuf.Bytes()), string(stderrBuf.Bytes())    fmt.Printf("\nout:\n%s\nerr:\n%s\n", outStr, errStr)}這是要測試的 bash 腳本:#!/bin/bashdeclare -a arr=("frontend" "backend" "middleware" "apigateway")for service in "${arr[@]}"do  sleep 1  echo $service-prod-secret.yamldone現在,我只在命令運行時輸出輸出到操作系統。Stdout(終端),但我想讓這個輸出逐行推送到一些地方(EX:socket)以顯示執行命令的進度,因為我有一個命令需要很長時間才能完成,很難只看到白屏而不知道命令的進度。輸出:frontend-prod-secret.yamlbackend-prod-secret.yamlmiddleware-prod-secret.yamlapigateway-prod-secret.yamlout:frontend-prod-secret.yamlbackend-prod-secret.yamlmiddleware-prod-secret.yamlapigateway-prod-secret.yaml我需要等待命令完成才能獲得輸出,但這需要很長時間。如何逐行(實時)引用輸出以推送到所需的某些位置?
查看完整描述

2 回答

?
梵蒂岡之花

TA貢獻1900條經驗 獲得超5個贊

您應該偵聽 stdout 和 stderr 緩沖區,并在它們獲取新數據時打印它們。


您可以使用掃描儀掃描緩沖區:


package main


import (

    "bufio"

    "fmt"

    "io"

    "os/exec"

)


func main() {

    cmd := exec.Command("test.sh")

    

    stdout, _ := cmd.StdoutPipe()

    stderr, _ := cmd.StderrPipe()

    _ = cmd.Start()


    scanner := bufio.NewScanner(io.MultiReader(stdout, stderr))

    scanner.Split(bufio.ScanWords)

    for scanner.Scan() {

        m := scanner.Text()

        fmt.Println(m)

    }

    _ = cmd.Wait()

}


打印數據在緩沖區中顯示的狀態(因此行與行之間存在休眠狀態)


frontend-prod-secret.yaml

backend-prod-secret.yaml

middleware-prod-secret.yaml

apigateway-prod-secret.yaml


查看完整回答
反對 回復 2022-08-01
?
斯蒂芬大帝

TA貢獻1827條經驗 獲得超8個贊

操作系統。StdOut正在尋找一個具有方法的接口,在編寫其輸出時,它將調用此方法。Write


我想逐行獲取此輸出并推送到某些位置(例如:套接字)


讓我舉個例子


import (

    "flag"

    "github.com/gorilla/websocket"

    "net/url"

)


var addr = flag.String("addr", "localhost:12345", "http service address")


// this function allows transmitting of output

// and command as chat message strings

type CommandChat struct {

    Conn *websocket.Conn

}


func ChatConnect() (c *CommandChat, err error) {

    u := url.URL{Scheme: "ws", Host: *addr, Path: "/echo"}

    conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)

    c = &CommandChat{Conn: conn}

    return

}


func (c *CommandChat) Write(input []byte) (n int, err error) {

    err = c.Conn.WriteMessage(websocket.TextMessage, input)

    return

}

func (c *CommandChat) Rx(resp []byte) (err error) {

    return

}

func (c *CommandChat) Close() (err error) { return }

現在您可以分配給CommandChatos.StdOut


chat, err := ChatConnect()

cmd.Stdout = chat


查看完整回答
反對 回復 2022-08-01
  • 2 回答
  • 0 關注
  • 146 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號