将输出重定向到 C 中的文件

发布于 2024-12-21 11:05:21 字数 470 浏览 1 评论 0 原文

我用 C 语言编写了一个基本 shell 来执行基本命令,它将执行命令 lsls -alls -al |更多

我想在我的 shell 中执行以下命令。 喜欢 ;

ls -al > a.txt

这将为我提供一个 a.txt 文件,其中包含 ls -al 进程的输出。 我找到了一个解决方案,它正在更改 shell 中的命令,例如 [command1] | tee [文件名]。在这种情况下,它将更改 ls -al > a.txtls -al | tee a.txt。但这个过程也将输出提供给文件和终端。如何停止在终端中打印输出。

或者有没有比使用 tee 命令更好的解决方案。 提前致谢...

i coded a basic shell in C for executing basic commands it'll execute commands ls, ls -al , ls -al | more etc.

i want to execute following command in my shell.
like ;

ls -al > a.txt

this will give me a.txt file which contain output of ls -al process.
i found a one solution, it's changing the command in my shell like [command1] | tee [filename]. in this instance it'll change ls -al > a.txt to ls -al | tee a.txt. but this process gives the output to file and terminal as well. how to stop printing output in terminal.

or are there are any better solution rather than using tee command.
thanks in advance...

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

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

发布评论

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

评论(3

大海や 2024-12-28 11:05:21

这是我用 dup2 测试的结果

更微妙的一点是在正确的时间记住 fflush :) 否则,你会得到非常令人惊讶的结果。

另外,更喜欢 fileno 而不是硬编码 1 (stdout) 2 (stderr)。

重定向 stdin 留给读者作为练习

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
    int out = open("cout.log", O_RDWR|O_CREAT|O_APPEND, 0600);
    if (-1 == out) { perror("opening cout.log"); return 255; }

    int err = open("cerr.log", O_RDWR|O_CREAT|O_APPEND, 0600);
    if (-1 == err) { perror("opening cerr.log"); return 255; }

    int save_out = dup(fileno(stdout));
    int save_err = dup(fileno(stderr));

    if (-1 == dup2(out, fileno(stdout))) { perror("cannot redirect stdout"); return 255; }
    if (-1 == dup2(err, fileno(stderr))) { perror("cannot redirect stderr"); return 255; }

    puts("doing an ls or something now");

    fflush(stdout); close(out);
    fflush(stderr); close(err);

    dup2(save_out, fileno(stdout));
    dup2(save_err, fileno(stderr));

    close(save_out);
    close(save_err);

    puts("back to normal output");

    return 0;
}

This is the result of my testing things out with dup2

The more subtle point is remembering fflush at the right times :) Otherwise, you'll get very surprising results.

Also, prefer fileno instead of hardcoding 1 (stdout) 2 (stderr).

Redirecting stdin was left as an exercise for the reader

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
    int out = open("cout.log", O_RDWR|O_CREAT|O_APPEND, 0600);
    if (-1 == out) { perror("opening cout.log"); return 255; }

    int err = open("cerr.log", O_RDWR|O_CREAT|O_APPEND, 0600);
    if (-1 == err) { perror("opening cerr.log"); return 255; }

    int save_out = dup(fileno(stdout));
    int save_err = dup(fileno(stderr));

    if (-1 == dup2(out, fileno(stdout))) { perror("cannot redirect stdout"); return 255; }
    if (-1 == dup2(err, fileno(stderr))) { perror("cannot redirect stderr"); return 255; }

    puts("doing an ls or something now");

    fflush(stdout); close(out);
    fflush(stderr); close(err);

    dup2(save_out, fileno(stdout));
    dup2(save_err, fileno(stderr));

    close(save_out);
    close(save_err);

    puts("back to normal output");

    return 0;
}
悲欢浪云 2024-12-28 11:05:21

当输出要发送到文件时,不要使用管道。

当您分叉子进程来运行 ls 命令时,您会记下重定向并打开文件;然后使用 dup2()(或 close() 和 dup()),以便文件描述符现在成为子级的标准输出;您关闭重复的文件描述符 - 由 open() 返回的文件描述符;然后你照常执行ls;它的标准输出现在被发送到文件。

请注意,非管道 I/O 重定向是在分叉之后而不是之前执行的。必须在分叉之前设置管道,但其他 I/O 重定向则不需要。

Don't use pipe when the output is to go to a file.

When you fork the child to run the ls command, you note the redirection, and open the file; you then use dup2() (or close() and dup()) so that the file descriptor is now standard output for the child; you close the duplicated file descriptor - the one returned by open(); then you execute ls as usual; its standard output is now sent to the file.

Note that you do the non-pipe I/O redirection after forking, not before. Pipes have to be set up before forking, but other I/O redirection does not.

长梦不多时 2024-12-28 11:05:21

在新创建的进程中调用 execve(2) 来执行命令之前,您可以通过 dup2(2)系统调用:

/* redirect stdout to a file */
dup2(1, some_open_file_descriptor);

当然,你需要有一些错误处理。

Before you call execve(2) in the newly created process to execute the command, you can redirect its standard input or output via the dup2(2) system call:

/* redirect stdout to a file */
dup2(1, some_open_file_descriptor);

Of course, you need to have some error handling.

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