子外壳的执行顺序?

时间:2018-08-31 11:03:42

标签: bash subshell

在尝试解决其他问题时,我在this question的Alex B的回答中遇到了以下bash脚本:

#!/bin/bash

(
  # Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
  flock -x -w 10 200 || exit 1

  # Do stuff

) 200>/var/lock/.myscript.exclusivelock

我在理解该脚本时遇到问题。根据{{​​1}}手册,flock's中的文件描述符(200)必须与 open 文件相关。

该描述符/文件在哪里打开?如果是flock -x -w 10 200打开描述符,则意味着这部分在子外壳程序之前执行,这与我最初查看此脚本时的想法相反

这引出我的问题:相对于主脚本(即打开子shell的脚本)以及相对于同一主脚本可能产生的其他子shell,bash中子shell的执行顺序是什么?

通过阅读其他文章和bash手册,我相信我仅了解到子外壳程序是“并发地”执行的,但是我没有看到任何说明解释是否有执行的语句(一个明显的例外是主程序脚本将需要一个子shell的输出,例如200>/var/lock/.myscript.exclusivelock

1 个答案:

答案 0 :(得分:1)

重定向操作符

200>使用描述符200打开文件。确实在子shell之前对其进行了处理。然后,该文件描述符由子Shell继承。

子外壳并没有固有的并发性。您可能会想到管道,例如a | b | c,其中abc都是同时运行的命令。每个操作都在子shell中运行(如果它们是外部命令,则通常是适当的子进程,但即使shell内置程序也在子shell中执行)也是管道的实现细节。


要详细说明,

  1. 首先,shell解析此命令。它使用输出重定向标识复杂的命令(...)

  2. 它将以写模式在文件描述符200上打开/var/lock/.myscript.exclusivelock

  3. 它执行子shell,该子shell继承了所有打开的文件描述符,包括200。

  4. 在子Shell中,它执行flock,该子程序从父级(子Shell)继承所有打开的文件描述符。根据其参数的要求,它在文件描述符200上执行其操作。

  5. 一旦子shell退出,由其重定向操作程序之一打开的任何文件都会被shell关闭。