Maison >développement back-end >Golang >Comment récupérer et traiter la sortie en temps réel des commandes Shell dans Go ?

Comment récupérer et traiter la sortie en temps réel des commandes Shell dans Go ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-11 04:40:14874parcourir

How to Retrieve and Process Real-Time Output from Shell Commands in Go?

Récupération de sortie en temps réel dans Go pour les commandes Shell

Dans Golang, le package os/exec fournit les moyens d'exécuter des commandes shell. Cependant, lorsque ces commandes renvoient une sortie en temps réel ou des mises à jour de progression, il devient nécessaire de récupérer et de traiter ces informations de manière dynamique. Voici comment y parvenir :

Pour capturer et traiter la sortie en temps réel d'une commande shell dans Go, envisagez l'approche suivante :

package main</p>
<p>importer (</p>
<pre class="brush:php;toolbar:false">"bufio"
"fmt"
"io"
"os"
"os/exec"
"strings"

)

func main() {

cmdName := "ffmpeg -i t.webm  -acodec aac -vcodec libx264  cmd1.mp4"
cmdArgs := strings.Fields(cmdName)

cmd := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...)
stderr, _ := cmd.StderrPipe()
cmd.Start()
go printProgress(stderr)
cmd.Wait()

}

// pour imprimer les informations traitées lorsque stderr obtient une nouvelle ligne
func printProgress(stderr io.ReadCloser) {

r := bufio.NewReader(stderr)
for {
    line, _, err := r.ReadLine()
    if err != nil {
        fmt.Println("error in reading from stderr:", err)
        break
    }

    // Process the line (e.g., extract the progress percentage)
    percentage, err := extractPercentage(string(line))
    if err != nil {
        fmt.Println("error in extracting percentage:", err)
        continue
    }

    // Print the updated progress ratio
    fmt.Printf("%s%%", percentage)
}

>

// extractPercentage analyse la ligne de sortie ffmpeg et renvoie la progression pourcentage.
// Cela suppose le format de sortie dans la question (par exemple, "frame=... size=... time=... bitrate=...")
func extractPercentage(line string) (chaîne, erreur) {

parts := strings.Split(line, " ")
if len(parts) < 4 {
    return "", fmt.Errorf("invalid line format: %s", line)
}

size := parts[2]
sizeUnits := []string{"B", "kB", "MB", "GB", "TB", "PB"}
for i, unit := range sizeUnits {
    if strings.HasSuffix(size, unit) {
        factor := float64(1 << (10 * i))
        sizeBytes, err := strconv.ParseFloat(strings.TrimSuffix(size, unit), 64)
        if err != nil {
            return "", err
        }

        percentage := (sizeBytes / factor) / 100
        return strconv.FormatFloat(percentage, 'f', 2, 64), nil
    }
}

return "", fmt.Errorf("unknown size unit: %s", size)

}

Cette approche utilise des canaux pour récupérer la sortie en temps réel du flux stderr de la commande. Il lit et traite en permanence la sortie, extrayant les informations de progression et les imprimant de manière dynamique. Notez que la fonction extractPercentage dans cet exemple extrait le pourcentage de la sortie ffmpeg, en supposant le format spécifique mentionné dans la question. Cela devra peut-être être ajusté en fonction du format de sortie spécifique de votre commande shell.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn