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
How to redirect the output of system() to a file?
提问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
stdout是FILE *标准输出流的指针。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
回答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 0、stdoutis1和stderris 2)。所以new_fd会4
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);- 这样做

