将标准输出重定向到文件

发布于 2025-01-16 21:56:26 字数 663 浏览 1 评论 0原文

我正在尝试执行与 C 中的 bash 命令 ls>foo.txt 等效的操作。

下面的代码将输出重定向到变量。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int main(){
  int pfds[2];
  char buf[30];

  pipe(pfds);

  if (!fork()) {
    close(pfds[0]);
     //close(1);//Close stdout
    //dup(pfds[1]);
    //execlp("ls", "ls", NULL);
    write(pfds[1], "test", 5); //Writing in the pipe
    exit(0);
  } else {
    close(pfds[1]);  
    read(pfds[0], buf, 5); //Read from pipe
    wait(NULL);
  }
  return 0;
}

注释行指的是我认为重定向所需的那些操作。 我应该更改什么才能将 ls 的输出重定向到 foo.txt?

I am trying to do the equivalent of the bash command ls>foo.txt in C.

The code bellow redirects the output to a variable.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int main(){
  int pfds[2];
  char buf[30];

  pipe(pfds);

  if (!fork()) {
    close(pfds[0]);
     //close(1);//Close stdout
    //dup(pfds[1]);
    //execlp("ls", "ls", NULL);
    write(pfds[1], "test", 5); //Writing in the pipe
    exit(0);
  } else {
    close(pfds[1]);  
    read(pfds[0], buf, 5); //Read from pipe
    wait(NULL);
  }
  return 0;
}

The comments lines refer to those operations that I believe that are required for the redirection.
What should I change to redirect the output of ls to foo.txt?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌无敌 2025-01-23 21:56:26

在处理将输出重定向到文件时,您可以使用 freopen()。

假设您是尝试将您的 stdout 重定向到文件“output.txt”,然后您可以

freopen("output.txt", "a+", stdout); 

在此处写入“a+”以表示附加模式。如果文件存在,则文件以附加模式打开。否则会创建一个新文件。

使用 freopen() 重新打开 stdout 后,所有输出语句(printf、putchar)都将重定向到“output.txt”。因此,之后任何 printf() 语句都会将其输出重定向到 'output.txt' 文件。

如果您想再次恢复 printf() 的默认行为(即在终端/命令提示符中打印),则必须使用以下代码再次重新分配 stdout -

freopen("/dev/tty", "w", stdout); /*for gcc, ubuntu*/  

或者-

freopen("CON", "w", stdout); /*Mingw C++; Windows*/ 

然而,类似的技术适用于“stdin”。

While dealing with redirecting output to a file you may use freopen().

Assuming you are trying to redirect your stdout to a file 'output.txt' then you can write-

freopen("output.txt", "a+", stdout); 

Here "a+" for append mode. If the file exists then the file open in append mode. Otherwise a new file is created.

After reopening the stdout with freopen() all output statement (printf, putchar) are redirected to the 'output.txt'. So after that any printf() statement will redirect it's output to the 'output.txt' file.

If you want to resume printf()'s default behavior again (that is printing in terminal/command prompt) then you have to reassign stdout again using the following code-

freopen("/dev/tty", "w", stdout); /*for gcc, ubuntu*/  

Or -

freopen("CON", "w", stdout); /*Mingw C++; Windows*/ 

However similar technique works for 'stdin'.

如痴如狂 2025-01-23 21:56:26

您的代码本质上是打开一个管道,然后分叉进程并在子进程中(在注释代码中)关闭标准输出,将管道复制到标准输出并执行 ls 命令,然后(在非注释代码中)写入4 个字节到管道。在父进程中,您从管道中读取数据并等待子进程完成。

现在您想将标准输出重定向到文件。您可以通过使用 open() 系统调用打开文件,然后将该文件描述符复制到 stdout 来做到这一点。类似的东西(我还没有测试过这个,所以要小心代码中的错误):

int filefd = open("foo.txt", O_WRONLY|O_CREAT, 0666);
if (!fork()) {
  close(1);//Close stdout
  dup(filefd);
  execlp("ls", "ls", NULL);
} else {
  close(filefd);
  wait(NULL);
}
return 0;

但是,您也可以按照其他答案的建议使用 freopen 。

但是,我对您的代码和我修改后的代码有几个担忧:

  • pipe() 和 open() 系统调用可能会失败。您应该始终检查系统调用失败。

  • fork() 系统调用可能会失败。同上。

  • 可以使用dup2()代替dup();否则,如果 stdin 未打开,代码将失败,因为它会复制到第一个可用的文件描述符。

  • execlp() 系统调用可能会失败。同上。

  • 我认为 wait() 可以被信号 (EINTR) 中断。建议将其包装在一个包装器中,如果系统调用被信号 (errno == EINTR) 中止,则该包装器会重试系统调用。

What your code essentially does is that you open a pipe, then fork the process and in the child process (in commented code) close stdout, duplicate the pipe to stdout and execute and ls command, and then (in non-commented code) write 4 bytes to the pipe. In the parent process, you read data from the pipe and wait for the completion of the child process.

Now you want to redirect stdout to a file. You can do that by opening a file using the open() system call and then duplicating that file descriptor to stdout. Something like (I haven't tested this so beware of bugs in the code):

int filefd = open("foo.txt", O_WRONLY|O_CREAT, 0666);
if (!fork()) {
  close(1);//Close stdout
  dup(filefd);
  execlp("ls", "ls", NULL);
} else {
  close(filefd);
  wait(NULL);
}
return 0;

However, you can also use the freopen as suggested by the other answer.

However, I have several concerns of your code and of my modified code:

  • The pipe() and open() system calls can fail. You should always check for system call failure.

  • The fork() system call can fail. Ditto.

  • dup2() can be used instead of dup(); otherwise the code will fail if stdin is not open as it duplicates to the first available file descriptor.

  • The execlp() system call can fail. Ditto.

  • I think wait() can be interrupted by a signal (EINTR). It's recommended to wrap it around a wrapper that retries the system call if it's aborted by a signal (errno == EINTR).

仅冇旳回忆 2025-01-23 21:56:26

“在 ubuntu 中使用终端进行测试”。

例如,您的代码是“mike.c”
你首先编译它

gcc mike.c

如果没有错误, ,
然后你

./a.out > file

会在与 mike.c 相同的目录(文件夹)中找到包含代码的文件,

请注意该文件可能是(file.txt,file.md ...)

希望这会有所帮助。

"tested using terminal in ubuntu" .

say for example your code is "mike.c"
you first compile it by

gcc mike.c

if there are no errors,
you then do

./a.out > file

you shall find your file containing the code in the same directory (folder) as mike.c

Note that file could be (file.txt, file.md ...)

hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文