Lecture de la première stdin en Aller?
Je voudrais lire à partir de l'original stdin
d'un programme de Go. Par exemple, si je n'ai echo test stdin | go run test.go
, je voudrais avoir accès à "test stdin". J'ai essayé la lecture de os.Stdin
, mais si il n'y a rien, alors il faudra attendre l'entrée. J'ai aussi essayé de vérifier la taille de la première, mais la os.Stdin.Stat().Size()
est de 0, même lorsque l'entrée est passé.
Que puis-je faire?
- Et stackoverflow.com/questions/3751429/... n'a pas aidé?
- Quelque chose comme "s = Système.dans.readline()" en java "ou" $s = <STDIN>" en perl, quelque chose de simple à faire quelque chose de simple???
- J'ai cette question de la vôtre réponse? Est quelque chose de pas clair? Si ne serait-il pas agréable de vous de marquer l'une des réponses comme acceptée.
Vous devez vous connecter pour publier un commentaire.
Je pense que votre question n'a en soi aucune réponse sensée, car il n'y a aucune une telle chose comme "initiale stdin". Os Unix-like, Windows et mettre en œuvre le concept de "flux standard", qui fonctionne comme ceci (simplifié): lorsqu'un processus est créé, il automagiquement a trois descripteurs de fichiers (poignées dans Windows) ouvrez — stdin, stdout et stderr. Pas de doutes, vous êtes familier avec ce concept, mais je tiens à souligner que le sens du mot "flux" il y a dans votre exemple, lorsque vous appelez
le shell crée un pipe, engendre deux processus (un pour
echo
et un pour votre binaire) et rend l'utilisation de la pipe qu'elle a créé: le tuyau d'écrire FD est attaché à laecho
s'stdout et le tuyau de lecture de la FD est attaché à votre binaire de l'entrée standard. Alors, quel que soit leecho
processus se plaît à écrire à sa sortie standard (stdout) est courante (sic!) pour le stdin de votre processus.(En réalité, la plupart aujourd'hui, les coquilles de l'œuvre
echo
qu'un primitif, mais ce n'est pas en aucune façon modifier la sémantique; vous pourriez aussi bien avoir essayé/bin/echo
au lieu de cela, ce qui est un réel programme. Notez également que j'ai simplement utilisé./stdin
de vous référer à votre programme — c'est pour plus de clarté, commego run stdin.go
serait faire exactement cela, en fin de compte.)Remarque plusieurs choses ici:
echo
dans votre cas) n'est pas oblidged rien écrire sur sa sortie standard (par exemple,echo -n
ne serait pas écrire quoi que ce soit à sa sortie standard et la sortie avec succès).read
est la tentative qui échoue).Laisser envelopper cette place: le comportement que nous observons est correct et normal. Si vous vous attendez à obtenir toutes les données à partir de stdin, vous ne devez pas attendre qu'il soit facilement disponible. Si vous aussi vous ne voulez pas bloquer sur stdin, puis créer une goroutine qui ferait de blocage lit l'entrée standard stdin dans une boucle sans fin (mais à vérifier les expressions du FOLKLORE état) et de transmettre les données recueillies jusqu'à plus d'un canal (éventuellement après le traitement, si nécessaire).
1 C'est pourquoi certains outils qui se produisent habituellement entre deux tuyaux dans un pipeline, comme
grep
, pourrait avoir des options spéciales pour les faire rincer leurs stdout après l'écriture de chaque ligne de lire au sujet de la--line-buffered
option dans legrep
de la page de manuel pour un exemple. Les personnes qui ne sont pas au courant de cette "pleine mise en mémoire tampon par défaut" sémantique est perplexe pourquoitail -f /path/to/some/file.log | grep whatever | sed ...
semble stagner et de ne pas afficher quoi que ce soit quand il est évident que la fichier surveillé est mis à jour.Comme une note de côté: si vous deviez exécuter le binaire "comme il est", comme dans
qui ne serait pas censé le pondu processus n'aurait pas stdin (ou "initial stdin" ou whaveter), au lieu de cela, son stdin serait relié à la même flux de votre shell reçoit votre clavier importer à partir d' (de sorte que vous pourriez taper directement quelque chose à votre processus stdin).
Le seul moyen sûr de disposer d'un processus de stdin connecté à nulle part est d'utiliser
sur Unix-like avec des Systèmes d'exploitation et
sur Windows. Cette "périphérique null" rend le processus de voir les expressions du FOLKLORE sur la première
read
de son stdin.echo -n
ne fait qu'écrire sur la sortie standard, il omet seulement le retour à la ligne. Aussi, le comportement n'est pas normal. Pour ces quantités de données (11 octets) il devrait y avoir aucun retard par préemption ou quelque chose de similaire.-n
est le seul argument. C'est ce que je voulais démontrer. Quant à la quantité de données, de préemption peut se produire partout, à tout moment: j'ai juste l'envoyerSIGSTOP
àecho
avant qu'il réussit à écrire pour le tuyau, par exemple. La seule guagantee que les tuyaux semblent fournir à cet égard, c'est que ceux de 11 octets arriverez à la conduite dans une pièce (non entrelacé), au moins c'est ce que je déduis de homme à la pipe(7).Lire stdin à l'aide de
os.Stdin
devrait fonctionner comme prévu:L'exécution de
echo test stdin | go run stdin.go
doit imprimer test "stdin" just fine.Il aiderait si vous souhaitez joindre le code utilisé pour identifier le problème que vous rencontrez.
Pour la ligne de base de la lecture, vous pouvez utiliser
bufio.Scanner
:bufio.Reader
.os.Stdin
?Vous ne pouvez pas vérifier stdin pour le contenu, mais vous pouvez vérifier si stdin est associé à un terminal ou d'un tuyau. IsTerminal prend juste le standard unix fd numéros (0,1,2). Le syscall paquet a des variables de sorte que vous pouvez faire syscall.Stdin si vous préférez les nommer.