使用 execvp 和 dup2 系统调用后写入终端时出现问题

problem in writing to terminal after using execvp and dup2 syscalls

第 15 行 { printf("This goes to the terminal\n"); } 未在终端或文件中的任何地方打印。

//inputs   argc = 3 :- ./executable_file  output_file  command
    int main(int argc, char **argv)
    {
        if(argc < 3)
        {
            return 0;
        }
        int stdout_copy = dup(1);
        int fd = open(argv[1], O_CREAT | O_RDWR | O_TRUNC, 0644);
        if (fd < 0)
        {
            printf("ERROR\n");
            return 0;
        }
        printf("This goes to the standard output(terminal).\n");
        printf("Now the standard output will go to \"%s\" file  .\n", argv[1]);
        dup2(fd, 1);
        printf("This output goes to \"%s\"\n",argv[1]);
        close(fd);
        execvp(argv[2],argv+2);
        dup2(stdout_copy,1);
        printf("This goes to the terminal\n");
        return 0;
    }

对上一个问题表示歉意: 真的很抱歉,是我分析的失误。 特别感谢所有的回答和提示。

使用 execvp 和 dup2 系统调用后写入终端时出现问题

两者都不是:

    execvp(argc[2],argc+2);
    dup2(stdout_copy,1);
    printf("This goes to the terminal\n");

或者:

    dup2(stdout_copy,1);
    execvp(argc[2],argc+2);
    printf("This goes to the terminal\n");

...如果调用 execvp(argc[2],argc+2); 成功,将输出到 stdout
但是,如果失败,两者都会输出到stdout
(除非命令行参数不正确,否则 dup2() 可能与无法输出到 stdout 无关。请参阅下面的其他内容以了解如何检查这一点。)

在此处阅读所有相关信息:execvp
在 nutshell 中,execvp() 将当前进程替换为新进程。如果成功,当前进程将不再是您在终端上看到的。只有成功才会执行后面的命令

以下建议并不完全 on-topic,但仍然很重要...

变化:

int main(int argv, char **argc)

收件人:

int main(int argc, char **argv)  //or  int main(int argc, char *argv[]), either are fine.

这将是看到正常行为的基础。其他任何事情都会让您的代码的未来维护者以及试图理解您在这里做什么的人感到困惑。
这些名称很容易记住,记住 argc 用于计算命令行参数,argv 是用于存储它们的 vector .

此外,您的代码没有显示您是 checking/validating 这些论点的迹象,但考虑到您程序的性质,应该在继续之前验证它们。例如:

//verify required number of command line arguments was entered
if(argc <!= 3)//requires at least one additional command line argument
{
    printf("Usage: prog.exe [path_filename]\nInclude path_filename and try again.\nProgram will exit.");
    return 0;
}
//check if file exists before going on
if( access( argv[1], F_OK ) != -1 ) 
{
     // file exists
} else {
     // file doesn't exist
}
//do same for argv[2]

(在 Linux 环境中检查文件的第二个示例来自 here

顺便说一句,了解传递到程序中的命令行参数将有助于在此处提供更明确的答案。它们的语法和内容,以及它们引用的文件是否存在,决定了对 execvp 的调用行为。

建议

  • 通常总是查看具有它们的函数的 return 值。但是由于 execvp 的独特行为,如果成功则不会 return,如果失败则始终 return -1。因此,在这种情况下,请特别注意 errno 的错误指示值,所有这些都包含在上面的 link 中。

  • 如评论中所述(在两个地方。)在解释标准 I/O 和文件描述符 [=27= 时,使用 fflush(stdout) 清空缓冲区是个好主意],以及在使用任何 exec*() 调用系列之前。

  • 花时间阅读 man 页面以了解所使用的功能 - shell 命令。它将节省时间,并在调试过程中为您提供指导。