【问题标题】:"more" as a target of piped command breaks bash“更多”作为管道命令的目标会破坏 bash
【发布时间】:2012-11-10 16:55:02
【问题描述】:

考虑以下来源,为简单起见减少

int main()
{
  int d[2];
  pipe(d);
  if(fork())
  {
    close(1);
    dup(d[1]);
    execlp("ls", "ls", NULL); 
  }
  else
  {
    close(0);
    dup(d[0]);
    execlp("cat", "cat", NULL); 
  }
}

因此它创建了一个管道并将输出从ls 重定向到cat

它工作得很好,没有问题。但是将 cat 更改为 more 并 bash 中断。

症状是:

  • 您没有看到您输入的任何内容
  • 按“enter”会显示一个新提示,但不是在新行中,而是在同一行中
  • 您可以执行任何命令并查看输出
  • reset 帮助解决问题。

所以键盘输入有问题,它在那里,但不可见。

这是为什么呢?

更新:

  • ls | more 的输出相当于我的程序的输出
  • more 进程没有完成,它被ls 孤立了
  • 唯一可见的问题是父进程退出后控制台的状态
  • 在某些系统上,它确实按预期工作。例如,在 OpenSUSE 上我没有问题,在 Kubuntu 上。我找不到任何关于我应该寻找哪些差异的信息,more 二进制文件在两个系统上都不同

【问题讨论】:

  • 它在我的系统上运行良好more ..
  • 有趣。在我的另一个系统上它也可以工作。所以它适用于 OpenSUSE,但不适用于 Kubuntu。那更令人迷惑:/

标签: c exec pipe


【解决方案1】:

因为与cat 不同,more 是一个交互式程序,它需要的不仅仅是stdinstdoutstderr——它需要一个终端,而您的系统调用无法提供这些终端。尝试在管道或脚本中运行more,看看会发生什么。

另请注意,bash 在任何阶段均不涉及,execlp 函数调用将当前进程替换为指定为参数的另一个进程。

【讨论】:

  • 好吧,ls | more 给了我与ls | cat 相同的结果,对于简短的输入。我当然知道这两者的区别。正如我在评论中提到的,它在 SUSE 上按预期工作,但在 Kubuntu 上却没有。不同的实现,也许不同的环境?我提到了bash,因为在父进程完成后结果是可观察的。子进程仍然存在。为什么?它是否尝试读取终端的大小并且未能检测到它是否足以输出?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 2017-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-18
相关资源
最近更新 更多