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

自古美人都是妖i 提交于 2019-12-18 16:57:21

问题


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 )


回答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");



回答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;
   }



回答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.




回答4:


use dup instead of dup2. dup creates a alias file descriptor, which value should be always the smallest available file descriptor.

new_fd = dup(file); - In this statement file might be having the value 3 (because stdin is 0, stdout is 1 and stderr is 2). so new_fd will be 4

If you want to redirect stdout into file. Then do as below.

close(stdout);
new_fd = dup(file);

Now dup will return 1 as the alias for the file descriptor, because we closed stdout so opened file descriptors are 0,2,3 and 1 is smallest available file descriptor.

If you are using dup2 means, dup2(file,1); - do like this



来源:https://stackoverflow.com/questions/11189490/how-to-redirect-the-output-of-system-to-a-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!