繁体   English   中英

如何判断孩子是否要求stdin?我怎么告诉它阻止它?

[英]How can I tell if a child is asking for stdin? How do I tell it to stop that?

在bash中,当我运行像wc &cat &这样的命令并立即想要标准时,它会立即返回

[1] +停止了猫

这是如何完成的? 如何停止我开始使用exec的程序,以及如何知道首先停止这些程序? 有没有办法告诉这些程序是否需要标准输入?

谢谢!

PS也,+约是什么? 我一直在想,但谷歌真的很难......

如果您希望衍生程序的行为与shell的工作方式类似,请在分叉您的孩子后调用setpgrp() 这将导致后台程序在其自己的进程组中运行,因此具有分离的tty。 当它尝试对控制台进行I / O时,它将接收SIGTTIN或SIGTTOU信号。 SIGTTIN或SIGTTOU的默认行为是像SIGSTOP一样停止进程。

作为父级,您可以使用waitpid()WUNTRACED找出是否已停止子进程。

[已编辑 - 请参阅主要问题答案的其他答案]

+号只是指当前的工作 每个命令管道(例如foo | bar | baz )都是一个作业,可以使用以%字符开头的jobspec来引用。 %1是作业编号1, %+是当前作业, %-是上一个作业。

有关作业的更多信息,请参阅Bash手册的“ 作业控制”部分

setpgid()手册页解释了它的工作原理:

会话可以具有控制终端。 在任何时候,会话中的一个(并且只有一个)进程组可以是终端的前台进程组; 其余进程组在后台。 如果从终端生成信号(例如,键入中断键以生成SIGINT ),则将该信号发送到前台进程组。 (有关生成信号的字符的说明,请参阅termios(3) 。)只有前台进程组可以从终端read(2) ; 如果后台进程组试图从终端read(2) ,则向该组发送SIGTSTP信号,该信号将其挂起。 tcgetpgrp(3)tcsetpgrp(3)函数用于获取/设置控制终端的前台进程组。

所以你想要做的是:

  1. 创建新管道时,调用setpgid()将管道的所有成员放入新的进程组(管道中第一个进程的PID作为PGID)。

  2. 使用tcsetpgrp()来管理哪个进程组在前台 - 如果你在后台放置一个带有&的管道,你应该让shell自己的进程组再次成为前台进程组。

  3. 使用WNOHANGWUNTRACED标志调用waitpid()来检查子进程的状态 - 这将在SIGTSTP停止时通知您,这将允许您打印类似bash的消息。

如果没有时间和优先级约束,您可以在分叉子进程中使用system("command &")然后手动使其退出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM