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 C
program
在这个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
stdout
is a FILE *
pointer of the standard output stream. dup2
expects 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 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
调用完成后恢复标准输出。您可以通过多种方式执行此操作。你可以dup
把它放在某个地方然后dup2
它回来(并关闭dup
ped 一个)。我个人不喜欢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 ls
as 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 dup
instead of dup2
. dup
creates a alias file descriptor, which value should be always the smallest available file descriptor.
使用dup
代替dup2
. dup
创建一个别名文件描述符,该值应始终是最小的可用文件描述符。
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
new_fd = dup(file);
- 在此语句中file
可能具有值3
(因为stdin
is 0
、stdout
is1
和stderr
is 2
)。所以new_fd
会4
If you want to redirect stdout
into file. Then do as below.
如果你想重定向stdout
到文件。然后做如下。
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.
现在 dup 将返回 1 作为file
描述符的别名,因为我们关闭了stdout
所以打开的文件描述符是0,2,3
并且1
是最小的可用文件描述符。
If you are using dup2
means, dup2(file,1);
- do like this
如果你使用的dup2
是手段,dup2(file,1);
- 这样做