Como podemos saber quando nosso aplicativo tem um stdin canalizado ou não?
os.Pipe
é um os.File
para que possamos usar File.Stat()
qual return a os.FileInfo
e podemos usar FileInfo.Size()
para ver se há algum dado disponível para leitura.
package main
import (
"os"
"fmt"
)
func main() {
fi, err := os.Stdin.Stat()
if err != nil {
panic(err)
}
if fi.Size() > 0 {
fmt.Println("there is something to read")
} else {
fmt.Println("stdin is empty")
}
}
Isso funcionará com, $ date | go run main.go
mas não $ curl http://www.google.com/ | go run main.go
.
Como curl
precisamos de algum tempo para enviar dados, sempre teremos 0 (zero) para FileInfo.Size()
.
Para fazer funcionar, temos que usar FileInfo.Mode()
.
package main
import (
"os"
"fmt"
)
func main() {
fi, err := os.Stdin.Stat()
if err != nil {
panic(err)
}
fmt.Printf("%vn", fi.Mode())
}
$ go run main.go
Dcrw--w----
$ date | go run main.go
prw-rw----
O que é isso?
File.Mode()
retornar uma FileMode
bandeira.
Você pode ver o que é cada letra aqui FileMode .
A bandeira que procuramos é os.ModeNamedPipe
. Quando esta bandeira está ativada , significa que temos um tubo.
package main
import (
"os"
"fmt"
)
func main() {
fi, err := os.Stdin.Stat()
if err != nil {
panic(err)
}
if fi.Mode() & os.ModeNamedPipe == 0 {
fmt.Println("no pipe :(")
} else {
fmt.Println("hi pipe!")
}
}
Desta forma, podemos saber quando nosso comando está recebendo stdout de outro processo.
Se você tiver alguma outra ideia comente.
Você pode comentar sobre meus erros de inglês também para que eu possa aprender.
Obrigado.