Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 子壳的执行顺序?_Bash_Subshell - Fatal编程技术网

Bash 子壳的执行顺序?

Bash 子壳的执行顺序?,bash,subshell,Bash,Subshell,在尝试解决其他问题时,我在中Alex B的回答中遇到了以下bash脚本: 我理解那个剧本有困难。根据flock的手册,flock-x-w 10 200中的文件描述符(200)必须与打开的文件相关 描述符/文件在哪里打开?如果打开描述符的是200>/var/lock/.myscript.exclusivelock,这意味着该部分在子shell之前执行,这与我最初查看该脚本时的想法相反 这就引出了我的问题:bash中子shell的执行顺序是什么,与主脚本(即打开子shell的脚本)以及与同一主脚本可

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

我理解那个剧本有困难。根据
flock的
手册,
flock-x-w 10 200
中的文件描述符(
200
)必须与打开的文件相关

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

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


通过阅读其他文章和bash手册,我相信我只了解到子shell是“并发”执行的,但我没有看到任何语句解释是否有来自此的执行(一个明显的例外是当主脚本需要子shell的输出时,如
echo foo$(cat bar)
)重定向操作符使用描述符200打开文件。它确实是在子shell之前处理的。然后,该文件描述符由子shell继承

子shell没有内在的并发性。您可能会想到管道,比如
a | b | c
,其中
a
b
c
都是并发运行的命令。每一个都在子shell中运行(如果它们是外部命令,通常是一个子流程本身,但即使shell内置程序也在子shell中执行),这是管道的一个实现细节


详细说明,

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

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

  • 它执行子shell,它继承所有打开的文件描述符,包括200个

  • 在子shell中,它执行
    flock
    ,它从其父级子shell继承所有打开的文件描述符。根据其参数的请求,它在文件描述符200上执行其操作

  • 一旦子shell退出,由其重定向操作符之一打开的任何文件都将被shell关闭


  • 请你详细说明一下好吗?是什么机制使bash在子shell之前执行
    200>…
    部分?毕竟,
    bash
    不知道以后需要这个文件描述符,因为
    bash
    不知道
    flock
    语法,所以它无法神奇地检测到它需要在主要部分之后执行子shell。当然可以。评估过程是解析命令行,在此过程中识别所有重定向。打开所需的文件,以便将正确的文件描述符传递给命令。子shell只是复合命令的一个示例(其他示例包括
    if
    语句、
    while
    语句和命令组
    {…}
    ),而不是简单的命令(它只是一个命令名及其参数)。
    flock
    只是作用于从其父级接收的文件描述符200,在本例中是subshell命令。好的,谢谢,接受和+1。您的解释清楚地表明,subshell调用加上重定向只是一个命令(而不是多个命令)。对我来说,这是理解的关键;出于某种原因,我最初没有完全清楚地意识到这一点。
    #!/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