Écriture de l'entrée standard stdin et de la lecture à partir de la sortie standard stdout (UNIX/LINUX/Programmation en C)
Je travaillais sur une mission où un programme a pris un descripteur de fichier comme argument (généralement à partir de la mère dans un exec appel) et de les lire à partir d'un fichier et écrit à un descripteur de fichier, et dans mes tests, j'ai réalisé que le programme de travail de la ligne de commande et ne pas donner une erreur si j'ai utilisé de 0, 1 ou 2 en tant que descripteur de fichier. Qui fait sens pour moi, sauf que je pourrais écrire sur stdin et l'afficher sur l'écran.
Est-il une explication pour cela? J'ai toujours pensé qu'il y avait une certaine protection sur stdin/stdout et vous ne pouvez certainement pas fprintf à stdin ou fgets de stdout.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
char message[20];
read(STDOUT_FILENO, message, 20);
write(STDIN_FILENO, message, 20);
return 0;
}
fprintf
à stdin
(bien que je ne peux pas trouver quelque chose dans la norme interdisant explicitement) mais qui n'a aucun effet si vous pouvez write
au descripteur de fichier 0.Quelle est exactement la différence? Ne sont-ils pas l'accomplissement de la même tâche?
Une carotte et un bâton pouvez faire la même chose tâche, et pourtant ils ne sont pas la même chose, il suffit de demander votre quartier convivial âne 🙂 Poignées standard C, les descripteurs sont POSIX.
OriginalL'auteur Tim | 2011-09-12
Vous devez vous connecter pour publier un commentaire.
De la tentative d'écriture sur un fichier marqué en lecture seule ou vice-versa serait la cause de
write
etread
pour retourner -1, et d'échouer. Dans ce spécifiques cas, stdin et stdout sont en fait le même fichier. En substance, avant que votre programme s'exécute (si vous n'en fais pas de redirection) que le shell va:Donc, stdin, out et err sont tous des copies de la même descripteur de fichier ouvert en lecture et écriture.
OriginalL'auteur Dave
Devrait fonctionner. Remarque - stdout mon être un endroit différent à partir de stdin (même sur la ligne de commande). Vous pouvez nourrir la sortie d'un autre processus comme stdin en vous processus, ou d'arranger le stdin/stdout être des fichiers.
fprintf/fgets ont un tampon de réduire ainsi le nombre d'appels système.
OriginalL'auteur Ed Heal
Meilleure supposition - stdin points à l'endroit où l'entrée est à venir à partir de votre terminal et stdout points où la production devrait aller, votre terminal. Depuis qu'ils pointent vers le même lieu, ils sont interchangeables(dans ce cas)?
ensuite, il sera en lecture/écriture à partir de/à ce que stdin/stdout points. C'était beaucoup de ce que.
OriginalL'auteur Avery3R
Si vous exécutez un programme sous UNIX
Vous pouvez ouvrir /proc/{pid}/fd/1 et en lire, ouvrir /proc/{pid}/fd/0 et écrire et, par exemple, copier
output
àinput
. (Il est peut-être un moyen plus simple de faire cela, mais je sais que ça fonctionne)Vous pouvez faire toutes sortes de choses qui sont simples à confusion si vous mettez votre esprit à lui. 😉
OriginalL'auteur Peter Lawrey
Il est très possible que les descripteurs 0, 1 et 2 sont tous ouvert à la fois pour la lecture et l'écriture (et, en fait, ils font tous référence à la même sous-jacent "description du fichier ouvert"), auquel cas ce que vous êtes faire fonctionne. Mais autant que je sache, il n'y a pas de garantie, de sorte qu'il peut également ne pas fonctionner. Je ne crois POSIX quelque part spécifie que si stderr est connecté le terminal lorsqu'un programme est appelé par le shell, c'est censé être accessible en lecture et en écriture, mais je ne trouve pas la référence de droit..
En général, je déconseille toujours de la lecture à partir de stdout ou stderr, sauf si vous êtes à la recherche d'un terminal de lecture d'un mot de passe, et stdin a été redirigé (pas un tty). Et je recommanderais jamais écrit sur stdin - c'est dangereux, et vous pourriez finir par casser un fichier que l'utilisateur ne s'attendait pas à être écrit!
OriginalL'auteur R..
Si vous voulez écrire un message dans stdin, vous pouvez ouvrir actuel ats, et d'appeler
write
appel système pour écrire un message à cette fd:De même, les lire à partir de la sortie standard stdout.
OriginalL'auteur vinllen