子shell的执行顺序?

Execution order of subshells?

在尝试解决其他问题时,我在 Alex B 在 this question 的回答中遇到了以下 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

我无法理解该脚本。根据 flock's 手册,flock -x -w 10 200 中的文件描述符(200)必须与 open 文件相关。

那个描述符/文件是在哪里打开的?如果是 200>/var/lock/.myscript.exclusivelock 打开描述符,那将意味着这部分在 之前 子 shell 执行,这与我最初看时的想法相反在这个脚本中。

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

通过阅读其他文章和 bash 手册,我相信我只了解到子 shell 被执行 "concurrently",但我没有看到任何解释是否有 execptions 的声明(一个明显的例外是当主脚本需要子 shell 的输出时,例如 echo foo $(cat bar)).

200>,重定向操作符,使用描述符200打开文件,确实在subshell之前处理。然后该文件描述符由 subshell.

继承

subshells 没有内在的并发性。您可能会想到 pipelines,例如 a | b | c,其中 abc 都是 [=54] 的命令=]同时。每个子 shell 中的每个都是 运行 的事实(通常是子进程本身,如果它们是外部命令,但即使是 shell 内置函数也在子 shell 中执行)是管道的实现细节。


详细说明,

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

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

  3. 它执行subshell,继承所有打开的文件描述符,包括200.

  4. 在子shell中,它执行flock,它从父级继承所有打开的文件描述符,子shell。它按照其参数的要求在文件描述符 200 上执行操作。

  5. 一旦 subshell 退出,由其重定向操作符之一打开的任何文件都会被 shell.

  6. 关闭