2017-07-04 4 views
1

J'ai le code suivant qui exécute une commande shell arbitraire et canalise la stdout et stderr au terminal .:Proxy exec.Cmd Stdout/Stderr sans perdre ATS

c := exec.Command("/bin/sh", "-c", cmd) 
c.Stdin = os.Stdin 
c.Stdout = os.Stdout 
c.Stderr = os.Stderr 

Cependant, je dois traiter la sortie avant de l'imprimer, donc je l'ai enveloppé avec un proxy Interface io.Writer:

type ProxyWriter struct { 
    file *os.File 
} 

func NewProxyWriter(file *os.File) *ProxyWriter { 
    return &ProxyWriter{ 
     file: file, 
    } 
} 

func (w *ProxyWriter) Write(p []byte) (int, error) { 
    // ... do something with bytes first 
    fmt.Fprintf(w.file, "%s", string(p)) 
    return len(p), nil 
} 

Ainsi, le code d'origine est maintenant:

c := exec.Command("/bin/sh", "-c", cmd) 
c.Stdin = os.Stdin 
c.Stdout = NewProxyWriter(os.Stdout) 
c.Stderr = NewProxyWriter(os.Stderr) 

Cela fonctionne pour la plupart, cependant, stdout et stderr ne semblent plus être admissibles comme ATS. Toute sortie de style ou de couleur n'est plus stylisée ou colorée.

J'ai confirmé que ce n'est pas un problème avec mon ProxyWriter simplement jouer avec le formatage en définissant la commande à la suivante, qui affiche correctement le texte coloré.

c := exec.Command("echo", "\033[0;31mTEST\033[0m") 

Un test plus explicite:

c := exec.Command("/bin/sh", "-c", "if [ -t 1 ] ; then echo \"terminal\"; else echo \"not a terminal\"; fi") 

qui délivre en sortie:

not a terminal 

Y at-il de toute façon je peux envelopper les commandes stdout/stderr sans perdre le statut ATS?

Répondre

0

Remplacer

func (w *ProxyWriter) Write(p []byte) (int, error) { 
    // ... do something with bytes first 
    fmt.Fprintf(w.file, "%s", string(p)) 
    return len(p), nil 
} 

Pour

func (w *ProxyWriter) Write(p []byte) (int, error) { 
    return w.Write(p) 
} 

fmt.Fprintf ont une certaine logique pour éviter de casser la borne.

+0

Je suppose que vous vouliez dire 'w.file.Write' plutôt que' w.Write'? La sortie est la même que 'fmt.Fprintf' malheureusement. – kbirk

+0

Avez-vous essayé? Et que voulez-vous dire «qualifier un TTY»? apparaissent des séquences d'échappement cassées? – mattn

+0

Oui, j'ai essayé d'utiliser 'return w.file.Write (p)'. Ce que je veux dire par «se qualifier comme un TTY», c'est que si j'emballe os.Stdout dans une interface io.Writer et y mets 'Cmd.Stdout', il ne sera pas qualifié de terminal. – kbirk