BASH_SUBSHELL 实现于 Bash 3.0,我一直想不到它在实际编码中有什么用,后来在 Bash 的 Change Log 里找到一句话,才知道它是作调试用的:

New variables to support the bash debugger: BASH_ARGC, BASH_ARGV,
BASH_SOURCE, BASH_LINENO, BASH_SUBSHELL, BASH_EXECUTION_STRING,
BASH_COMMAND

BASH_SUBSHELL 是 subshell 嵌套层次的累加器,那么按理说,所有的 subshell 里这个变量都应该加 1。那 Bash 的哪些语法是在 subshell 里执行的呢?下面列举一下:

  1. 小括号分组 (...)
  2. 命令替换 `...` 和 $(...)
  3. 进程替换 <() 和 >()
  4. 管道 ... | ...
  5. 后台命令 ... &

那么当 BASH_SUBSHELL 出现在这些语法中时,它的值就应该加 1,对不对?然而实际情况却不是这样的,在我写这篇文章时,Bash 的最新稳定版是 4.3.30,在该版本中,BASH_SUBSHELL 只会在上面列出的 1 和 2 两种语法里生效:

$ (echo $BASH_SUBSHELL)

1

$ echo `echo $BASH_SUBSHELL`

1

$ echo $(echo $BASH_SUBSHELL)

1

在后三种语法里不生效:

$ cat <(echo $BASH_SUBSHELL)

0

$ echo $BASH_SUBSHELL | cat

0

$ echo $BASH_SUBSHELL &

[1] 91155

$ 0

搜索了一翻,在 help-bash 上发现已经有人提了个 bug,不过他仅仅提到了进程替换和命令替换中 BASH_SUBSHELL 表现不一致的事,Bash 作者也回复说会在 Bash 下个版本也就是是 4.4 里修复。然后我下了 4.4 alpha 版编译之后发现,进程替换中 BASH_SUBSHELL 是生效了,但在管道和后台命令中仍没效果,于是我又顶起了这个邮件,询问 Bash 作者是否能一起修复,他的回复是,后台命令那个他会修的,但管道命令那个不准备修复。然后我就没再追问为什么了,应该是实现上有困难,毕竟这是 Bash 私有的东西,作者有权决定该不该修。总之,我想说的是,在未来 Bash 4.4 发布的时候,BASH_SUBSHELL 在除了管道之外的其他子 Shell 里,都应该能生效了。

此外,当我问这个问题的时候,有人回复说,之所以 BASH_SUBSHELL 为 0,是因为它是在父 Shell 里展开之后才传入子 Shell 的,也就是说,echo $BASH_SUBSHELL | cat 在传入子 Shell 的时候就已经成了 echo 0 | cat,但这是不对的,我们可以举一个反例,如果真是那样的话,echo $BASHPID | cat 应该和 echo $BASHPID 的输出一样,但实际却是不一样的。所以可以总结一下就是,从来都不存在“在父 Shell 中展开变量,在子 Shell 里执行展开后的命令” 这一回事,所有的变量都是在子 Shell 中展开然后执行的。

BASH_SUBSHELL 变量不生效的情况的更多相关文章

  1. 详解Windows不重启使环境变量修改生效(经典)

    在“我的电脑”->“属性”->“高级”->“环境变量”中增加或修改环境变量后,需重启系统才能使之生效.有没有什么方法可让它即时生效呢?下面介绍一种方法: 以修改环境变量“PATH”为 ...

  2. windows10系统修改JDK版本后配置环境变量不生效怎么办

    之前安装了个jdk8版本,今天突然想安装个更新版本的jdk11来用,但在安装好JDK11并配置环境变量后发现修改JDK版本后配置的环境变量不生效的.本文就给大家分享一下windows10系统修改JDK ...

  3. window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法

    window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法 本机已经安装了jdk1.7,而比较早期的项目需要依赖jdk1.6,于是同时在本机安装了jdk1.6和jdk1.7. 安装 ...

  4. bat脚本设置系统环境变量即时生效

    关于bat的资料多但零碎,记录一下. 1.设置环境变量即时生效:通过重启explorer来实现即时生效(亲测有效) @echo off set curPath=%cd% wmic ENVIRONMEN ...

  5. bootstrap插件fileinput.js 出现出现$("#xxxx").fileinput({}); 不生效的情况解决

    如果出现$("#xxxx").fileinput({}); 不生效的情况请将fileinput.js中最后几行注释掉: /* $(document).ready(function ...

  6. Java中关于变量的几种情况

    Java中关于变量的几种情况 1.继承时变量的引用关系 class Animals { int age = 10; void enjoy() { System.out.println("An ...

  7. (转载)设置环境变量永久生效和临时生效 export PS1

    source/etc/profile是让/etc/profile文件修改后立即生效, 还有一种方法是:. /etc/profile 注意:.和/etc/profile有空格 linux中source命 ...

  8. [错误记录_C] 还未给指针变量正确赋值的情况下,就使用它的值

    错误的代码: 错误的结果:  错误原因分析: 在使用(1) 将pB,pC的值赋给pA的lchild和rchild时: 还未给指针变量pB和pC赋值,现在pB和pC中存的是个垃圾值 Note: (2)- ...

  9. 解决修改JDK环境变量不生效方法

    解决修改JDK环境变量不生效方法 brupsuit1.7在安装时一直报错jdk版本低,我就将jdk1.6版本的卸了换成1.8的,结果修改了环境变量但它一直给我不生效.... 1.之前版本未卸载干净 进 ...

随机推荐

  1. 一致性算法RAFT详解

    原帖地址:http://www.solinx.co/archives/415?utm_source=tuicool&utm_medium=referral一致性算法Raft详解背景 熟悉或了解 ...

  2. 发一份shiro标准配置,特此记录

    主要还是整合了本地ehcache,集群session管理过段时间放出 <?xml version="1.0" encoding="UTF-8"?> ...

  3. BZOJ 2330: [SCOI2011]糖果 [差分约束系统] 【学习笔记】

    2330: [SCOI2011]糖果 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5395  Solved: 1750[Submit][Status ...

  4. <<MySchool数据库设计优化>> 内部测试

    1) 在SQL Server 中,为数据库表建立索引能够( C ). A. 防止非法的删除操作 B. 防止非法的插入操作 C. 提高查询性能 D. 节约数据库的磁盘空间 解析:索引的作用是通过使用索引 ...

  5. jquery的各种隐藏显现动画的区别

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8&quo ...

  6. LeetCode:Multiply Strings

    题目链接 Given two numbers represented as strings, return multiplication of the numbers as a string. Not ...

  7. 如何修改Total Commander配件文件的位置

    今天测试了一下Total Commander最新版的安装文件,测试完成后,并删除.结果导致原先一直在使用的绿色版的Total Comander配件文件变成了测试的配件文件,导致许多配置都丢失了,因此不 ...

  8. SignalR主动通知订阅者示例

    html代码: <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script> <scri ...

  9. getline数据来源你的三种方式

    (1)getline从交互式的用户输入中\c中获取内容: # awk 'BEGIN {system("echo \"Input your name:\"");g ...

  10. MVC复杂模型绑定

    当初遇到业务需求ajax提交一组对象数组到服务器.但是苦于mvc的默认绑定器.绑定不上去.好吧只有靠自己了. 当初就是参考这个大大的博客:http://www.cnblogs.com/xfrog/ar ...