stdout
是标准输出流的FILE *
指针。而dup2
函数期望文件描述符,你也搞混了参数的顺序。
请使用:
dup2(file, 1);
相反地。
关于更好的做法部分。这种方法不好,因为在 system
调用完成后,您可能希望恢复标准输出。您可以通过多种方式实现这一点。您可以将其 dup
到某个位置,然后 dup2
回来(并关闭 dup
)。我个人不喜欢按照其他答案中建议的编写自己的 cat
实现。如果您想要的唯一一件事是将单个 shell 命令与 system
重定向到文件系统中的文件,则最直接且简单的方法可能是构造执行此操作的 shell 命令,如下所示:
system("ls -l > Result");
但是如果文件名(Result)来自用户输入,您必须小心,因为用户可以提供像'Result; rm -rf /*'
这样的文件名。
此外,在安全方面,建议在评论中指定ls
的完整路径:
system("/bin/ls -l > Result");
"ls"
,这会改变系统调用的含义。问题也与绝对路径或相对路径无关。我认为最好询问 @unkulunkulu 是否愿意修改他的答案。 - Andomar>
:#include <stdio.h>
int main()
{
system("ls -l > /some/file");
return 0;
}
另一种选择是使用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;
}
使用dup
代替dup2
。 dup
创建一个别名文件描述符,其值应始终为最小可用文件描述符。
new_fd = dup(file);
- 在此语句中,file
可能具有值3
(因为stdin
是0
,stdout
是1
,stderr
是2
)。 因此,new_fd
将是4
如果您想将stdout
重定向到文件,则请按以下方式操作。
close(stdout);
new_fd = dup(file);
现在,dup将返回1作为file
描述符的别名,因为我们关闭了stdout
,所以打开的文件描述符是0,2,3
,而1
是最小可用的文件描述符。
如果您正在使用dup2
,意味着dup2(file,1);
- 就像这样
dup()
而不是 dup2()
只有在您不关心副本放置位置时才这样做。如果您关心,请使用 dup2()
-- 这是它的显式目的!如果您只是希望一切顺利,就像这个答案所做的那样,它会正常工作,直到某一天模式被打破,您将不知道为什么它失败了。这些都会导致一些令人恼火的深夜调试会话,而这些本可以通过从一开始就正确地执行来避免。 - mah>
运算符重定向system()
输出的方法,我建议使用FILE *freopen(const char *filename, const char *mode, FILE *stream)
函数(它是stdio.h头文件的一部分)。在我看来,这是最能代表>
运算符的方式。# include <stdio.h>
# include <stdlib.h>
int main(void){
char line[1024];
FILE *handle = freopen("result.txt", "w", stdout);
if(!handle)
exit(EXIT_FAILURE); //file didn't open
sprintf(line, "ls -l");
system(line);
return 0;
}
system()
。这样做可以简化需要使用不同参数执行相同命令的情况。
system
命令中使用>
重定向符号? - Alvin Wongsystem("ls -l > Result");
或者自己编写fork()
/exec*()
组合。 - Hristo Ilievsystem
,这总是错误的。自己运行子进程而不使用 shell,可以使用fork
和execvp
或posix_spawn
。 - R.. GitHub STOP HELPING ICEsystem
应该被视为已弃用,因为 (1) 很难对它进行任何有用的操作,而且 (2) 尝试对其进行任何有用的操作(例如传递参数)几乎肯定会创建与 shell 转义相关的危险(可能涉及安全问题)的错误。 - R.. GitHub STOP HELPING ICE