Zum umleiten von printf() auf Datei und dann zurück auf die Konsole
Arbeite ich an einem Projekt, das erfordert mir zu haben, die Ausgabe in eine mini-shell auf meinem C-Programm, um die Ausgabe in eine Datei. Mit ./program > file.txt
wird NICHT funktionieren.
Habe ich ein mini-shell-Programm, das läuft, kleine Befehle, und ich möchte es so machen, wenn jemand einen > filename
am Ende eines Befehls, es leitet den gesamten text aus printf()
einer Datei statt von der Konsole, und dann leitet es zurück in die Konsole.
Wie kann ich dies in C?
fork()
,dup2()
,execvp()
-- die-Taste, im Kontext wirddup2()
, die nur benötigt werden, wenn diefork()
, damit die Eltern nicht haben, um futz mit Ihren eigenenstdout
.- verwenden
freopen
.. - Mit
freopen()
arbeitet man die Datei, wie schalten Sie dann? Zumindest gibt es mehr zu tun als nur den Aufruffreopen()
. - ist dieses Hausaufgaben?
- Können Sie ein Beispiel geben? Ich habe versucht, mit fork() und dup2() vor, aber es schien nicht zu funktionieren.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Normale shell mit fork und exec
Wenn Sie eine normale shell, wo Sie sind mit
fork()
undexecvp()
oder einen seiner verwandten, dann sollten Sie die Gabel der Kind-Prozess und in der child-handle des I/O-Umleitung (mitopen()
,dup2()
oderdup()
, undclose()
), so dass die Eltern die I/O unverändert.Vorausgesetzt, Sie haben analysiert den Befehl in:
und die standard-Ausgabe-Datei-Namen in:
dann:
Beachten Sie, dass die Eltern nicht die standard-Ausgabedatei.
Können Sie auch die Reihenfolge:
Umleiten integrierte Befehle ohne Gabel und exec
Ganz abgesehen von der Umlenkung in den falschen Prozess, mit
freopen()
oder vielleichtfdopen()
und Wiedereröffnung/dev/stdout
wird nicht funktionieren. Die Datei, die/dev/stdout
Punkte, um änderungen, wie das Programm ausgeführt und die Dateien werden geöffnet, geschlossen oder als Hauptprogramm ändert sich, was seine Datei-Deskriptor 1 (standard-output) Punkte an.Wenn Sie wirklich brauchen, um die Umleitung der standard-Ausgabe des Haupt-shell für einen built-in, wo die
fork()
undexec()
-Familie ist nicht für alle Funktionen verwendet, dann müssen Sie das gleiche:Funktionierenden code
OK. Ich habe von vornherein die Allgemeingültigkeit der ein Zeiger auf die Funktion für den built-in Befehl, die ich zuerst codiert; ich Schloss es würde wahrscheinlich verwechseln Sie mehr. Ich lehne ab, zu tun, ohne ein "Druck-Fehler" - Funktion (obwohl ich oft es Rindfleisch bis zum Bericht über
errno
mitstrerror()
sowie Druck-die basic-Fehlermeldung).Rief ich die source-Datei
simpleshell.c
und das Programm dahersimpleshell
, aber das ist über-fordern, was es tut.Beispiel-Ausgabe
execvp(argv[0], argv);
ist für?warning: implicit declaration of function ‘fork’
Auch, Es läuft, ist es eigene Befehle, keine "echte" linux-Befehle.fork()
und die Aufmerksamkeit auf die Warnungen; danke! Die relevanten header fürfork()
ist<unistd.h>
; ditodup()
et al. Allerdingsopen()
erfordert<fcntl.h>
.Können Sie freopen.
Sobald Sie fertig sind, können Sie rückgängig machen, die Umwidmung wie diese:
auf Unix/Linux Systeme. Ich bin mir nicht sicher, ob es eine portable Möglichkeit, wieder zurück.
UPDATE
Wenn möglich, können Sie
fprintf
stattprintf
, die entwederstdout
oder ein handle für die gewünschte Datei.freopen()
arbeitet man die Datei, wie schalten Sie dann? Zumindest gibt es mehr zu tun als nur den Aufruffreopen()
./dev/stdout
verweist auf die Datei, wenn Sie anrufenfreopen()
zweiten mal...stdout
wurde, wies auf die Datei./dev/tty
,con
odercon:
für windowsdup()
oderdup2()
, und dann können Sie vielleicht mitfreopen()
auf/dev/fd/N
wo N ist der Wert, den Sie dupliziertstdout
in den ersten Platz. Es gibtfileno()
, undfdopen()
relevant sein könnten auch. Aber ich denke, die Frage ist, fehlt der Punkt -- es ist der untergeordnete Prozess, Bedürfnisse zu behandeln. In reinen (POSIX) shell, die Sie verwenden könnten:{ exec 3>&1 >desiredFileName; execute commands...; exec 1>&3 3>&-; }