我正在尝试编写一个最终会利用并发性的 shell。现在我有一个工作的 shell 解析器,但我无法弄清楚如何执行命令。我看了一点exec
(execvp
等),它看起来很有希望,但我有一些问题。
exec 可以处理文件输入/输出重定向吗?我可以使用 exec 设置管道吗?
我也想知道子壳。子shell应该返回什么;最后一条语句的退出状态?子壳可以成为管道的一部分吗?
这些可能看起来很愚蠢的问题,但请忍受我的经验不足。
exec 可以处理文件输入/输出重定向吗?
不,您可以使用open()
anddup()
或dup2()
(and close()
) 来执行此操作。
我可以使用 exec 设置管道吗?
不,你用pipe()
, dup()
ordup2()
和很多 close()
电话来做到这一点。
我也想知道子壳。subshells 应该返回什么,它最后一条语句的退出状态?
这是正常的约定,是的。
子壳可以成为管道的一部分吗?
是的。在普通的 shell 中,您可以编写如下内容:
(cd /some/where; find . -name '*.png') | sed 's/xyz/prq/' > mapped.namelist
如果你想害怕,你可以调查posix_spawn()
它的支持功能。在POSIX 2008站点上搜索“spawn” ,并做好害怕的准备。我认为临时进行映射工作实际上比使用posix_spawn()
及其支持者对其进行编码更容易。
shell 的标准技术是使用fork-exec。在此模型中,为了执行应用程序,shell 使用fork创建一个新进程,该进程是其自身的副本,然后使用其中一个 exec 变体将其自己的代码、数据等替换为可执行文件指定的信息在磁盘上。
这个模型的好处是,shell 可以在更改其地址空间之前对文件描述符(不会被 exec 丢弃)做一些额外的工作。因此,为了实现重定向,它将文件描述符 0、1 和 2(分别为 stdin、stdout 和 stderr)更改为指向另一个打开的文件,而不是控制台 I/O。您使用dup2更改这些文件描述符之一的含义,然后使用 exec 启动新进程。