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.之前版本未卸载干净 进 ...
随机推荐
- WSTMall网站系统最新官方版
WSTMall V1.0是在thinkphp 的经典版本3.2.2基础上进行优化开发的, TP 3.2.2不是thinkphp的一个最新的版本,却是thinkphp最金典的一个版本,正所谓站在巨人的肩 ...
- Vim插件管理
一.简介 二.管理器 1)Vundle https://github.com/gmarik/vundle.git 2)vim-plug https://github.com/junegunn/vim- ...
- BI领导驾驶舱的功能特点
随着企业的信息化能力越来越强,商业智能(BI)对他们而言已不仅仅是数据展现的工具.商业智能必须能够与企业的业务流程相联系,做企业随需随用的“战略军师”.“BI领导驾驶舱”的出现无疑顺应了BI的发展趋势 ...
- 匈牙利算法 cogs 886. [USACO 4.2] 完美的牛栏
886. [USACO 4.2] 完美的牛栏 ★★☆ 输入文件:stall4.in 输出文件:stall4.out 简单对比时间限制:1 s 内存限制:128 MB USACO/sta ...
- OpenFlow:Enabling Innovation in Campus Networks
SDN领域,OpenFLow现在已经成为了广泛使用的南向接口协议.若想好好学习SDN,在这个领域有所进步,需要熟悉OpenFlow协议.我最近找了篇有关OpenFLow的论文,发现最早该协议是在Sig ...
- 网格弹簧质点系统模拟(Spring-Mass System by Fast Method)附源码
弹簧质点模型的求解方法包括显式欧拉积分和隐式欧拉积分等方法,其中显式欧拉积分求解快速,但积分步长小,两个可视帧之间需要多次积分,而隐式欧拉积分则需要求解线性方程组,但其稳定性好,能够取较大的积分步长. ...
- Properties类读取配置文件
package com.wzy.t4; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFound ...
- ASP.NET(C#) Web Api通过文件流下载文件到本地实例
下载文件到本地是很多项目开发中需要实现的一个很简单的功能.说简单,是从具体的代码实现上来说的,.NET的文件下载方式有很多种,本示例给大家介绍的是ASP.NET Web Api方式返回HttpResp ...
- eclipse的几个快捷键
Alt / 自动补全 Ctrl Shift F 整理代码 Ctrl / 注释或取消注释 Ctrl 鼠标移到变量或类名上 转到声明/实现的接口/返回类型等 Ctrl Shift O import所有缺失 ...
- Markdown 11种基本语法
markdown真的很方便! 我根据自己在github上维护的项目编写的readme文件总结一些最基本的使用方法 ,学完这些Markdown的基本使用已经不成问题. 1. 标题设置(让字体变大,和wo ...