Nuovi Processi
Il package exec
permette l'esecuzione di comandi di sistema operativo da dentro i programmi Go.
La funzione Command()
registra il comando in un oggetto comando.
La funzione Output()
lo esegue e ritornare lo standard output del comando ed un errore.
Prima dell'esecuzione del comando è possibile la ridirezione dello standard input e output da e in pipes.
Il comando viene poi lanciato con la funzione Start()
dell'oggetto comando.
(620spawning-processes.go):
package main
import "fmt"
import "io/ioutil"
import "os/exec"
func main() {
// Esecuzione di comando senza argomenti
dateCmd := exec.Command("date")
// Output ed errore del comando
dateOut, err := dateCmd.Output()
if err != nil {
panic(err)
}
fmt.Println("> date")
fmt.Println(string(dateOut))
// Comando con argomento
grepCmd := exec.Command("grep", "hello")
// Input del comando da stdin
grepIn, _ := grepCmd.StdinPipe()
// Output a stdout
grepOut, _ := grepCmd.StdoutPipe()
// Lancio del comando
grepCmd.Start()
// Fornire l'input
grepIn.Write([]byte("hello grep\ngoodbye grep"))
// Chiudere l'input - importante
grepIn.Close()
// Lettura dell'output risultante
grepBytes, _ := ioutil.ReadAll(grepOut)
// Attesa della terminazione del processo - importante
grepCmd.Wait()
// Ognuno dei comandi sopra può ritornare un errore
// Controllo omesso in questo esempio
// Stampa del risultato
fmt.Println("> grep hello")
fmt.Println(string(grepBytes))
// Invocazione di shell e passaggio di argomenti
// alla shell - argomenti: un'unica stringa
lsCmd := exec.Command("bash", "-c", "ls -a -l -h")
lsOut, err := lsCmd.Output()
if err != nil {
panic(err)
}
fmt.Println("(through shell)> ls -a -l -h")
fmt.Println(string(lsOut))
// Invocazione diretta: ogni opzione o argomento
// è una stringa separata
lsCmd = exec.Command("ls", "-a", "-l", "-h")
lsOut, err = lsCmd.Output()
if err != nil {
panic(err)
}
fmt.Println("(standalone)> ls -a -l -h")
fmt.Println(string(lsOut))
}
Una pipe è composta da un oggetto di input ed un oggetto di output.
Quando l'input è da una pipe è importante chiuderlo esplicitamente con la funzione Close()
dell'oggetto di input che invia un End Of File (EOF).
La funzione ReadAll()
dell'oggetto di output legge l'output finale di una pipe.
Dato che una pipe è una serie di processi Linux indipendenti e sincronizzati, è importante attendere la terminazione di tutti questi processi con la funzione Wait()
dell'oggetto comando.