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.之前版本未卸载干净 进 ...
随机推荐
- import com.sun.image.codec.jpeg.JPEGCodec不通过 找不到包
import com.sun.image.codec.jpeg.JPEGCodec; 在Eclipse中处理图片,需要引入两个包: import com.sun.image.codec.jpeg. ...
- POJ2115 C Looooops[扩展欧几里得]
C Looooops Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 24355 Accepted: 6788 Descr ...
- JSP 错题
(选择一项) 8 A: B: C: D: 正确答案是 D 您回答的是 A 回答错误 试题分析:web容器处理JSP文件请求的三个阶段翻译阶段:这一个阶段,编写好的jsp文件首先被web容器中的 ...
- 第27章 java I/O输入输出流
java I/O输入输出流 1.编码问题 import java.io.UnsupportedEncodingException; /** * java涉及的编码 */ public class En ...
- PAT 1038. 统计同成绩学生(20)
本题要求读入N名学生的成绩,将获得某一给定分数的学生人数输出. 输入格式: 输入在第1行给出不超过105的正整数N,即学生总人数.随后1行给出N名学生的百分制整数成绩,中间以空格分隔.最后1行给出要查 ...
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 能支撑10万以上客户端的数据同步下载问题
庞大的业务系统,特别是需要有离线作业操作支持的核心业务系统,需要有强大的基础数据同步功能,基础数据有在增加.有在变动.有在失效,同时有大量的客户端全天侯的在连接服务器.不间断的在处理核心数据. 经过2 ...
- 在C#项目中需要用double类型操作MSSQL float类型数据(附C#数据类型和SQL数据类型对照)
C#操作SQL Float类型,数据会多很多小数,原来是C#的float和sql的float类型不一致.以下是数据库中与C#中的数据类型对照. /// <summary> /// 数据库中 ...
- Oracle 11g导出空表、少表的解决办法
ORACLE 11G中有个新特性,当表无数据时,不分配segment,以节省空间. 解决方法: 1)insert一行,再rollback就产生segment了 该方法是在在空表中插入数据,再删除,则产 ...
- jQuery链式操作[转]
用过jQuery的朋友都知道他强大的链式操作,方便,简洁,易于理解,如下 $("has_children").click(function(){ $(this).addClass( ...
- PRINCE2
首先要说的是,我这篇体会是针对一定的背景的,不能算是一种通用的管理方式,只能是我自己的经验总结,能给大家平常的管理提供一点思路,我就很满足了.先说说背景,我所在公司做的是大型桌面应用软件,简单点说就是 ...