How to redirect the output of system() to a file?
Solution 1
stdout
is a FILE *
pointer of the standard output stream. dup2
expects file descriptor, also you've messed up the parameters order.
Use
dup2(file, 1);
instead.
On the better-way-to-do-this part. This way is bad because you probably want to restore your standard output after this system
call completes. You can do this in a variety of ways. You can dup
it somewhere and then dup2
it back (and close the dup
ped one). I personally don't like writing own cat
implementations as suggested in other answers. If the only thing you want is redirecting a single shell command with system
to a file in the filesystem, then probably the most direct and simple way is to construct the shell command to do this like
system("ls -l > Result");
But you have to be careful if filename (Result) comes from user input as user can supply something like 'Result; rm -rf /*'
as the filename.
Also, on the topic of security, you should consider specifying the full path to ls
as suggested in the comments:
system("/bin/ls -l > Result");
Solution 2
The simple thing is to use >
indeed:
#include <stdio.h>
int main()
{
system("ls -l > /some/file");
return 0;
}
An alternative is using popen()
, something along the lines of
#include <stdio.h>
#include <stdlib.h>
main()
{
char *cmd = "ls -l";
char buf[BUFSIZ];
FILE *ptr, *file;
file = fopen("/some/file", "w");
if (!file) abort();
if ((ptr = popen(cmd, "r")) != NULL) {
while (fgets(buf, BUFSIZ, ptr) != NULL)
fprintf(file, "%s", buf);
pclose(ptr);
}
fclose(file);
return 0;
}
Solution 3
You should use the popen()
library function and read chunks of data from the returned FILE *
and write them to whatever output file you like.
Eight
Updated on April 15, 2020Comments
-
Eight about 4 years
In this
C
program#include <stdio.h> #include <fcntl.h> int main() { int file = open("Result", O_CREAT|O_WRONLY, S_IRWXU); dup2(stdout, file); system("ls -l"); return 0; }
I'm trying to redirect the output of system() to a file, for that i have used dup2 but it is not working.
What's wrong with this code?
and, please tell me if there is any better way to do this? (without using>
at the terminal ) -
Wug almost 12 yearsI edited your post to include an absolute path to ls in your example.
-
Andomar almost 12 yearsReverted edit because the OP runs
"ls"
and this would change the meaning of the system call. The question is also unrelated to absolute or relative paths. I think it's better to ask @unkulunkulu if he would like to revise his answer. -
unkulunkulu almost 12 years@Andomar, actually, I accepted the edit, but anyway, both your points are valid, I don't see a difference :) Wug, thanks for suggestion, it will be seen in the comments anyway.
-
Andomar almost 12 years@unkulunkulu: don't hesitate to reverse my change if you agree with Wug. You can do so by clicking on the "edited X mins ago" and choosing "revert" for the appropriate revision.
-
Wug almost 12 yearsCalling system without specifying an absolute path is generally a very bad idea because of the potential for tricksy individuals to break your program by playing with PATH. Not a good mistake for a beginner to get into the habit of. Hence, my edit.
-
mah over 10 yearsUsing
dup()
instead ofdup2()
is only if you don't care where the duplicate is placed. If you care, usedup2()
-- that's its explicit purpose! If instead you simply hope for the best, as this answer does, it will work fine until one day the pattern breaks and you won't have any idea why it fails. Those make for some aggravating late night debug sessions which could have been avoided by simply doing it the right way from the start.