Lesen Sie von der ersten Stufe in GO?
Ich Lesen möchte, von der ursprünglichen stdin eines go-Programm. Zum Beispiel, wenn ich echo test stdin | go run test.go
ich würde wollen, um Zugang zum "test " stdin". Ich habe versucht, das Lesen von os.Stdin
aber wenn es nichts in ihm, dann wird es warten, bis Eingang. Ich habe auch versucht, anhand der Größe den ersten, aber die os.Stdin.Stat().Size()
ist 0, auch bei der Eingabe übergeben wird.
Was kann ich tun?
InformationsquelleAutor der Frage mowwwalker | 2012-09-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, deine Frage per se keine vernünftige Antwort, weil es einfach keine solche Sache als "erste stdin". Unix-ähnlichen Betriebssystemen und Windows-Umsetzung des Konzepts "standard streams"die funktioniert wie folgt (vereinfacht): wenn ein Prozess erstellt wird, wird es automatisch hat drei Dateideskriptoren (handles in Windows) öffnen — stdin, stdout und stderr. Kein Zweifel, du bist vertraut mit diesem Konzept, aber ich möchte betonen die Bedeutung des Wortes "Strom" gibt es — in Ihrem Beispiel, wenn Sie anrufen
die shell erstellt eine Rohrerzeugt zwei Prozesse (einer für
echo
und eine für Ihre binäre) und macht die Verwendung des Rohres angelegt: die pipe zu schreiben, dass FD verbunden ist, um denecho
's stdout und pipe-lese-FD ist an Ihrem binäre stdin. Was immer dann derecho
Prozess gefällt zu schreiben, um seine stdout geleitet (sic!) an den stdin des Prozesses.(In der Realität der meisten heutigen shells implementieren
echo
wie ein eingebauter primitiv, aber dies gilt nicht in irgendeiner Weise ändern Sie die Semantik; Ihr könnte auch versucht haben/bin/echo
statt, das ein echtes Programm ist. Beachten Sie auch, dass ich nur./stdin
zu finden im Programm — dies ist für die Klarheit, wiego run stdin.go
würde genau das tun, am Ende.)Beachten Sie einige wichtige Dinge hier:
echo
in Ihrem Fall) nicht oblidged, etwas zu schreiben, um seine stdout (zum Beispielecho -n
würde nicht alles schreiben, was auf seine stdout und beendet erfolgreich).read
wird versucht, die fehlschlägt).Let ' s wrap up: das Verhalten, Sie sind Beobachtung ist korrekt und normal. Wenn Sie erwarten, zu bekommen, die Daten von stdin, müssen Sie nicht erwarten, dass es sofort verfügbar ist. Wenn Sie auch nicht wollen, zu blockieren, auf stdin, dann erstellen Sie eine goroutine, die tun würde, die Blockierung liest von der Standardeingabe in einer Endlosschleife (aber die überprüfung für die EOF-Bedingung) und übergeben die gesammelten Daten über einen Kanal (evtl. nach Verarbeitung, wenn nötig).
1 Dies ist, warum bestimmte tools, die in der Regel auftreten, zwischen zwei Rohrleitungen in eine Rohrleitung, wie
grep
vielleicht haben spezielle Optionen, um Sie leeren Ihre stdout, nach schreiben jeder Zeile Lesen über die--line-buffered
option in dergrep
manual-Seite für ein Beispiel. Menschen, die nicht bewusst sind, diese "volle Pufferung von Standard -" Semantik sind verwirrt, warumtail -f /path/to/some/file.log | grep whatever | sed ...
scheint zu hängen und kein display nichts, wenn es offensichtlich, dass die überwachten Datei wird aktualisiert.Als Randbemerkung: wenn Sie zu laufen waren Ihre binäre "wie Sie ist", wie in
wäre das nicht bedeutete, dass der erzeugte Prozess nicht hätte stdin (oder "ersten " stdin" oder whaveter), stattdessen, seine stdin verbunden wäre, um den gleichen Strom Ihre Schale erhält Ihre Tastatur import aus (so konnte man direkt geben Sie etwas, um Ihren Prozess stdin).
Der einzig sichere Weg, um einen Prozess stdin verbunden, nirgendwo ist die Verwendung
auf Unix-artigen Betriebssystemen und
unter Windows. Diese "null-Gerät" macht den Prozess sehen EOF-auf den ersten
read
von seinem stdin.InformationsquelleAutor der Antwort kostix
Lesen von stdin mit
os.Stdin
sollte funktionieren wie erwartet:Ausführung
echo test stdin | go run stdin.go
sollte print 'test stdin' just fine.Würde es helfen, wenn Sie möchten, befestigen Sie den code, den Sie verwendet, um das problem zu identifizieren, denen Sie begegnen.
Für Zeile durch die Lektüre, die Sie verwenden können
bufio.Scanner
:InformationsquelleAutor der Antwort nemo
Können Sie nicht überprüfen, stdin für den Inhalt, aber Sie können überprüfen, ob stdin verbunden ist, mit einem terminal oder einer pipe. IsTerminal braucht nur die standard-unix fd zahlen (0,1,2). Die syscall-Paket-Variablen zugewiesen, so dass Sie tun können, syscall.Stdin, wenn Sie es vorziehen benennen.
InformationsquelleAutor der Antwort John Eikenberry