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 dup2 but 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 )
这段代码出了什么问题?并且,请告诉我是否有更好的方法来做到这一点? (不在终端使用>)
4 个解决方案
#1
5
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的单个shell命令重定向到文件系统中的文件,那么可能最直接和最简单的方法是构造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.
但是如果文件名(结果)来自用户输入,你必须要小心,因为用户可以提供类似'结果; 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");
#2
4
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;
}
#3
2
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 *中读取数据块,并将它们写入您喜欢的任何输出文件。
#4
0
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); - 在此语句中,文件的值可能为3(因为stdin为0,stdout为1,stderr为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作为文件描述符的别名,因为我们关闭了stdout所以打开的文件描述符是0,2,3并且1是最小的可用文件描述符。
If you are using dup2
means, dup2(file,1);
- do like this
如果你使用dup2手段,dup2(文件,1); - 这样做
#1
5
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的单个shell命令重定向到文件系统中的文件,那么可能最直接和最简单的方法是构造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.
但是如果文件名(结果)来自用户输入,你必须要小心,因为用户可以提供类似'结果; 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");
#2
4
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;
}
#3
2
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 *中读取数据块,并将它们写入您喜欢的任何输出文件。
#4
0
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); - 在此语句中,文件的值可能为3(因为stdin为0,stdout为1,stderr为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作为文件描述符的别名,因为我们关闭了stdout所以打开的文件描述符是0,2,3并且1是最小的可用文件描述符。
If you are using dup2
means, dup2(file,1);
- do like this
如果你使用dup2手段,dup2(文件,1); - 这样做