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

Posted

技术标签:

【中文标题】c shell 输入重定向保持打开状态【英文标题】:c shell input redirection stays open 【发布时间】:2013-06-08 08:30:49 【问题描述】:

我正在使用以下代码部分为我的自定义 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 中读取成功,但没有返回或停止。

【问题讨论】:

【参考方案1】:

孩子仍然打开了 in_file。你必须在执行之前关闭它:

dup2(in_file, STDIN_FILENO);
close(in_file);

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

【讨论】:

【参考方案2】:

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

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

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

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

【讨论】:

我通过将 argv[0] 发送到我的 stderr 进行了检查,但 argv[0] 的内容是 grep

以上是关于c shell 输入重定向保持打开状态的主要内容,如果未能解决你的问题,请参考以下文章

linux shell脚本编程笔记: 重定向

Linux编程 22 shell编程(输出和输入重定向,管道,数学运算命令,退出脚本状态码)

Shell重定向

小鸟初学Shell编程输入输出重定向

Linux Shell系列教程之(十六) Shell输入输出重定向

Linux之Shell编程(12)--Shell输入/输出重定向实例演示