BASH_SUBSHELL 变量不生效的情况
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 里执行的呢?下面列举一下:
- 小括号分组 (...)
- 命令替换 `...` 和 $(...)
- 进程替换 <() 和 >()
- 管道 ... | ...
- 后台命令 ... &
那么当 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 变量不生效的情况的更多相关文章
- 详解Windows不重启使环境变量修改生效(经典)
在“我的电脑”->“属性”->“高级”->“环境变量”中增加或修改环境变量后,需重启系统才能使之生效.有没有什么方法可让它即时生效呢?下面介绍一种方法: 以修改环境变量“PATH”为 ...
- windows10系统修改JDK版本后配置环境变量不生效怎么办
之前安装了个jdk8版本,今天突然想安装个更新版本的jdk11来用,但在安装好JDK11并配置环境变量后发现修改JDK版本后配置的环境变量不生效的.本文就给大家分享一下windows10系统修改JDK ...
- window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法
window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法 本机已经安装了jdk1.7,而比较早期的项目需要依赖jdk1.6,于是同时在本机安装了jdk1.6和jdk1.7. 安装 ...
- bat脚本设置系统环境变量即时生效
关于bat的资料多但零碎,记录一下. 1.设置环境变量即时生效:通过重启explorer来实现即时生效(亲测有效) @echo off set curPath=%cd% wmic ENVIRONMEN ...
- bootstrap插件fileinput.js 出现出现$("#xxxx").fileinput({}); 不生效的情况解决
如果出现$("#xxxx").fileinput({}); 不生效的情况请将fileinput.js中最后几行注释掉: /* $(document).ready(function ...
- Java中关于变量的几种情况
Java中关于变量的几种情况 1.继承时变量的引用关系 class Animals { int age = 10; void enjoy() { System.out.println("An ...
- (转载)设置环境变量永久生效和临时生效 export PS1
source/etc/profile是让/etc/profile文件修改后立即生效, 还有一种方法是:. /etc/profile 注意:.和/etc/profile有空格 linux中source命 ...
- [错误记录_C] 还未给指针变量正确赋值的情况下,就使用它的值
错误的代码: 错误的结果: 错误原因分析: 在使用(1) 将pB,pC的值赋给pA的lchild和rchild时: 还未给指针变量pB和pC赋值,现在pB和pC中存的是个垃圾值 Note: (2)- ...
- 解决修改JDK环境变量不生效方法
解决修改JDK环境变量不生效方法 brupsuit1.7在安装时一直报错jdk版本低,我就将jdk1.6版本的卸了换成1.8的,结果修改了环境变量但它一直给我不生效.... 1.之前版本未卸载干净 进 ...
随机推荐
- 关于stm32定时器的理解
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 表面意思是输出控制极性为高,但是意思是定时器输入0,不反相,输出0: 输出控制极性为 ...
- hdfs 通过NFSV3 加载至本地目录
常常会有这种需求,把HDFS的目录MOUNT到本地目录,然后方便使用LINUX下面的命令直接操作. FUSE也可以达到同样的效果,但是配置比较复杂,新的HADOOP版本都建议使用NFS3来完成这个需求 ...
- 模-数(A/D)转换器
一.A/D转换的基本原理 在一系列选定的瞬间对模拟信号进行取样,然后再将这些取样值转换成输出的数字量,并按一定的编码形式给出转换结果. 整个A/D转换过程大致可分为取样.量化.编码三个过程.二.取样- ...
- 【2016-10-17】【坚持学习】【Day8】【抽象工厂模式】
定义: 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类. 结构: 抽象工厂类 具体工厂类 抽象产品类 具体产品类 例子: 代码: interface SkinFactory { B ...
- BZOJ 1070: [SCOI2007]修车 [最小费用最大流]
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 4936 Solved: 2032[Submit][Status] ...
- .jshintrc配置
在root目录创建一个.jshintrc文件插入下面的代码即可.也可以自行配置. { // // 强制选项 // // When set to true, these options will mak ...
- c#导出bugfree3.0的数据到禅道
环境:vs2012MVC4项目,mysql server5.6 准备:bugfree的数据库导出后.sql文件,禅道7.1的数据库文件 基本过程:这是个笨办法,也没有优化过代码,导入数据时候比较慢.禅 ...
- 原创jquery插件treeTable(转)
由于工作需要,要直观的看到某个业务是由那些子业务引起的异常,所以我需要用树表的方式来展现各个层次的数据. 需求: 1.数据层次分明: 2.数据读取慢.需要动态加载孩子节点: 3.支持默认展开多少层. ...
- JS组件系列——分享自己封装的Bootstrap树形组件:jqTree
前言:之前的一篇介绍了下如何封装自己的组件,这篇再次来体验下自己封装组件的乐趣.看过博主博客的园友应该记得之前分享过一篇树形菜单的使用JS组件系列——Bootstrap 树控件使用经验分享,这篇里面第 ...
- 基于Nginx dyups模块的站点动态上下线并实现简单服务治理
简介 今天主要讨论一下,对于分布式服务,站点如何平滑的上下线问题. 分布式服务 在分布式服务下,我们会用nginx做负载均衡, 业务站点访问某服务站点的时候, 统一走nginx, 然后nginx根据一 ...