How to redirect the output of system() to a file?

28,807

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 dupped 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.

Reference.

Share:
28,807
Eight
Author by

Eight

Updated on April 15, 2020

Comments

  • Eight
    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
    Wug almost 12 years
    I edited your post to include an absolute path to ls in your example.
  • Andomar
    Andomar almost 12 years
    Reverted 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
    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
    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
    Wug almost 12 years
    Calling 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
    mah over 10 years
    Using dup() instead of dup2() is only if you don't care where the duplicate is placed. If you care, use dup2() -- 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.