隐藏Execve命令的终端输出

8

我正在编写一个C程序,它基本上从用户那里读取一行输入,然后解释该命令并尝试使用execve执行。如果输入中包含'&',我还会将execve分叉到子进程中。

现在我希望隐藏来自子进程中运行的execve命令的任何终端输出。 有相对简单的方法可以做到这一点吗?

2个回答

6
您可以通过在fork之后但在execve()之前将stdout和stderr重定向到/dev/null来隐藏输出。其想法是打开/dev/null,然后使用dup2()将stdout和stderr复制为获得的文件描述符的副本(这也将首先关闭原始文件描述符)。这几乎与重定向到管道相同。
以下是一个示例(不完整的程序,并跳过大部分错误检查):
  #include <unistd.h>
  #include <fcntl.h>
  ...

  int pid = fork();
  if (pid == -1) {
    /* fork error */
    exit(1);
  } else if (pid == 0) {
    /* child process */

    /* open /dev/null for writing */
    int fd = open("/dev/null", O_WRONLY);

    dup2(fd, 1);    /* make stdout a copy of fd (> /dev/null) */
    dup2(fd, 2);    /* ...and same with stderr */
    close(fd);      /* close fd */

    /* stdout and stderr now write to /dev/null */
    /* ready to call exec */

    execve(cmd, args, env);
    exit(1);
  } else {
    /* parent process */

  ...

-1

我写了一个简单的例子,也许可以帮到你。

首先,尝试在不加 | echo $1 > /dev/null 的情况下调用它 - 它应该打印文件。当你添加它时,输出为空。

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

int main()
{
        int ret;
        char *cmd[] = { "ls", "-l", (char *)0 };
        char *env[] = {(char *)0 };
        ret = execve ("/bin/ls | echo $1 > /dev/null", cmd, env);
        return 0;
}

2
这应该不起作用(对我来说确实如此)。它尝试使用的IO重定向将由shell处理 - 但是execve不使用shell运行命令。它之所以似乎起作用,只是因为当execve失败时,根本没有运行/bin/ls - Dmitri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接