Linux 如何将 system() 的输出重定向到文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11189490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 07:02:16  来源:igfitidea点击:

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

clinuxsystemstdoutdup

提问by Eight

In this Cprogram

在这个C程序中

#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 dup2but it is not working.

我正在尝试将system()的输出重定向到一个文件,为此我使用了dup2但它不起作用。

What's wrong with this code?
and, please tell me if there is any better way to do this? (without using >at the terminal )

这段代码有什么问题
并且,请告诉我是否有更好的方法来做到这一点?(不在>终端使用)

采纳答案by unkulunkulu

stdoutis a FILE *pointer of the standard output stream. dup2expects file descriptor, also you've messed up the parameters order. Use

stdoutFILE *标准输出流的指针。dup2期待文件描述符,你也搞砸了参数顺序。用

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 systemcall completes. You can do this in a variety of ways. You can dupit somewhere and then dup2it back (and close the dupped one). I personally don't like writing own catimplementations as suggested in other answers. If the only thing you want is redirecting a single shell command with systemto a file in the filesystem, then probably the most direct and simple way is to construct the shell command to do this like

在更好的方式做这部分。这种方式很糟糕,因为您可能希望在此system调用完成后恢复标准输出。您可以通过多种方式执行此操作。你可以dup把它放在某个地方然后dup2它回来(并关闭dupped 一个)。我个人不喜欢cat按照其他答案中的建议编写自己的实现。如果您唯一想要的是将单个 shell 命令重定向system到文件系统中的文件,那么可能最直接和最简单的方法是构造 shell 命令来执行此操作

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.

但是如果文件名(结果)来自用户输入,你必须小心,因为用户可以提供类似'Result; rm -rf /*'文件名的东西。

Also, on the topic of security, you should consider specifying the full path to lsas suggested in the comments:

此外,关于安全主题,您应该考虑ls按照评论中的建议指定完整路径:

system("/bin/ls -l > Result");

回答by trojanfoe

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.

您应该使用popen()库函数并从返回的数据块中读取数据FILE *并将它们写入您喜欢的任何输出文件。

Reference.

参考

回答by johannes

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

另一种方法是使用popen(),类似于

   #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;
   }

回答by rashok

use dupinstead of dup2. dupcreates a alias file descriptor, which value should be always the smallest available file descriptor.

使用dup代替dup2. dup创建一个别名文件描述符,该值应始终是最小的可用文件描述符。

new_fd = dup(file);- In this statement filemight be having the value 3(because stdinis 0, stdoutis 1and stderris 2). so new_fdwill be 4

new_fd = dup(file);- 在此语句中file可能具有值3(因为stdinis 0stdoutis1stderris 2)。所以new_fd4

If you want to redirect stdoutinto file. Then do as below.

如果你想重定向stdout到文件。然后做如下。

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

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

现在 dup 将返回 1 作为file描述符的别名,因为我们关闭了stdout所以打开的文件描述符是0,2,3并且1是最小的可用文件描述符。

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

如果你使用的dup2是手段,dup2(file,1);- 这样做