C shell输入重定向保持打开状态

c shell input redirection stays open

本文关键字:状态 shell 输入 重定向      更新时间:2023-10-16

我使用以下代码部分为我的自定义c++ shell执行输入重定向。虽然与此类似的输出重定向工作得很好,但输入重定向的子进程保持打开状态并且不返回,就像它一直等待新输入一样。"要求"或"强制"这样的子进程在读取输入后立即返回的最佳方法是什么?

输入重定向代码
int in_file = open(in, O_CREAT | O_RDONLY , S_IREAD | S_IWRITE);
pid_t pid = fork();
    if (!pid) {
         dup2(in_file, STDIN_FILENO);
         if (execvp(argv[0], argv) < 0) {
             cerr << "*** ERROR: exec failed: "<< argv[0] << endl;
             exit(EXIT_FAILURE);
         }
     }
close(in_file);
输出重定向代码
out_file = open(out, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
pid_t pid = fork();
    if (!pid) {
         dup2(out_file, STDOUT_FILENO);
         if (execvp(argv[0], argv) < 0) {
             cerr << "*** ERROR: exec failed: "<< argv[0] << endl;
             exit(EXIT_FAILURE);
          }
    }    
close(out_file);
我使用以下命令进行测试:
ps aux > out.txt
grep root < out.txt

第一个命令在成功写入out.txt后返回到shell。第二个命令成功地从out.txt读取,但没有返回或停止。

子文件仍然打开着in_file。你必须在exec:

之前关闭它
dup2(in_file, STDIN_FILENO);
close(in_file);

(为了简洁,省略了错误检查)。因为子进程仍然有一个打开的文件描述符,所以它永远不会看到文件被关闭,所以它在读取时阻塞,等待有人写更多的数据。子进程没有意识到它是保持打开文件描述符的进程。另一个选项是为文件描述符设置'close-on-exec'标志,以便在执行时自动关闭它。(查找FD_CLOEXEC)

首先,检查execvp()的参数。如果此代码是main(int argc, char* argv[])的一部分,那么argv[0]是您自己的程序,而不是grep。这意味着你的程序永远在递归地重新执行自己。

然后,确保打开in时没有错误:

if (in_file < 0) { perror(in); ... }

如果in_file是一个无效的描述符,dup2()将失败,grep将从终端读取,因此,不终止。顺便说一句,使用O_CREAT | O_RDONLY看起来很可疑。为什么要从以前不存在的文件中读取?