SHLVL 环境变量代表 Shell 嵌套执行的深度。
$ echo $SHLVL 1 $ bash $ echo $SHLVL 2 $ bash $ echo $SHLVL 3 |
在 Bash 里,这个值的范围是 [0, 1000],0 是怎么来的呢?是在上次的 SHLVL 值为负数的时候:
$ SHLVL=-1 $ bash $ echo $SHLVL 0 |
当 SHLVL 的值超过 1000 时,会自动重置到 1。
$ SHLVL=1000 $ bash bash: warning: shell level (1001) too high, resetting to 1 $ echo $SHLVL 1 |
我也本以为就是这样了,然而却发现个特例:
$ SHLVL=999 $ bash $ echo $SHLVL |
在嵌套 1000 层的时候,SHEVL 看起来是个空字符串,但在 Shell 里很多东西眼见都不为实,所以我们用 16 进制看看:
$ SHLVL=999 bash -c 'echo -n "$SHLVL" | hexdump' 0b 01 $ SHLVL=999 bash -c 'echo -n "$SHLVL" | hexdump' 0f 01 $ SHLVL=999 bash -c 'echo -n "$SHLVL" | hexdump' 04 01 |
这个值原来是个随机字符串,在我的 Mac 上是两个控制字符(不可见字符),所以看起来像是空字符串。而在另外一台 Red Hat 上执行了下是一些肉眼可见的乱码:
$ SHLVL=999 bash -c 'echo "$SHLVL"' �[g� |
总之,也就是说 SHEVL 实际的值会在 [0, 999] 以及这个不确定的值这 1001 个值里轮询,不会真正到达 1000。
看了下 Bash 源码:
void
adjust_shell_level (change)
int change;
{
char new_level[], *old_SHLVL;
intmax_t old_level;
SHELL_VAR *temp_var; old_SHLVL = get_string_value ("SHLVL");
if (old_SHLVL == || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == )
old_level = ; shell_level = old_level + change;
if (shell_level < )
shell_level = ;
else if (shell_level > )
{
internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level);
shell_level = ;
} /* We don't need the full generality of itos here. */
if (shell_level < )
{
new_level[] = shell_level + '';
new_level[] = '\0';
}
else if (shell_level < )
{
new_level[] = (shell_level / ) + '';
new_level[] = (shell_level % ) + '';
new_level[] = '\0';
}
else if (shell_level < )
{
new_level[] = (shell_level / ) + '';
old_level = shell_level % ;
new_level[] = (old_level / ) + '';
new_level[] = (old_level % ) + '';
new_level[] = '\0';
} temp_var = bind_variable ("SHLVL", new_level, );
set_auto_export (temp_var);
} static void
initialize_shell_level ()
{
adjust_shell_level ();
}
它把数字转字符串的逻辑只写到 shell_level < 1000 的地方,漏掉了最后一个 else 的样子,导致 SHLVL 的值成为了一个未初始化的字符串。我在 bug-bash 上发了邮件,这个 bug 会在 Bash 4.4 中修复 http://lists.gnu.org/archive/html/bug-bash/2015-09/msg00057.html。顺便说一句,ksh 和 zsh 都没有这个 1000 限制。
Bash 中 SHLVL 变量为 1000 的时候的更多相关文章
-
bash 中的变量
bash 中的变量 Linux command line 笔记 变量无需声明,自动创建 var=abc #变量a赋值为字符串abc var="hello world" #字符串里有 ...
-
Bash中的变量
Bash中的变量1.用户定义的变量变量的定义 用户定义的变量有字母数字及下划线组成,并且变量名的第一个字符不能为数字. 与其它UNIX名字一样,变量名是大小写敏感的. 对于变量 ...
-
在Linux系详解Linux bash中的变量
(大讲台:国内首个it在线教育混合式自适应学习) 统中进行日常运维或者是编写脚本时,变量是再熟悉不过的了,但这些变量都有哪些类型,具体的用法又有哪些差异呢?本文整理分享给大家: 一.bash变量类型: ...
-
Linux bash中的变量分类
1.本地变量 VAR=XYZ 2.局部变量 local VAR=XYZ 3.环境变量 在子shell中可以起作用 export VAR=XYZ 4.位置变量 $0 脚本名本身 $1 第一个参数 $2 ...
-
bash中声明变量方法
bash提供了declare命令来声明变量,该命令的基本语法如下: declare attribute variable 其中,attribute表示变量的属性,常用的属性有如下所述. ...
-
bash 中的变量可以这么用
举个例子: t.sh ====================== #!/bin/bash ./a.sh ./b.sh ======================= a.sh =========== ...
-
Bash简明教程--变量
1. 前言 Bash是一门流行在*nix系统下的脚本语言.作为一门脚本语言,变量是一门语言的基本要素,在这篇教程中,我们将学习Bash中的变量是怎么表示的,以及变量相关的一些语法规则. 2. Bash ...
-
bash中一些基础知识
bash是linux操作系统的shell.以下是Multi-Perspective Sentence Similarity Modeling论文实现时碰到的一个bash: #!/bin/bash py ...
-
(二)shell中的变量
1.常用系统变量 $HOME.$PWD.$SHELL.$USER等 2.自定义变量 基本语法: (1)定量变量:变量=值 (2)撤销变量:unset 变量 (3)声明静态变量:readonly变量 注 ...
随机推荐
-
ahjesus sql手动重新更新ID
declare cus_cursor cursor scroll for SELECT Id from [dbo].[TLotterySpiderRule] open cus_cursor decla ...
-
Android中UI线程与后台线程交互设计的5种方法
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...
-
java.lang.NullPointerException错误分析
java.lang.NullPointerException是什么错误 你使用了空的指针.在java中虽然号称抛弃了C++中不安全的指针,但其实他所有的东西你都可以理解为指针.这种情况一般发生在你使用 ...
-
动态的加载显示oracle警告日志文件内容
Last login: Fri Jan 25 00:37:47 2019 from oracle [root@oracle ~]# su - oracle [oracle@oracle ~]$ sql ...
-
Windows系统下在Eclipse中集成Python
我现在偶尔开发代码,已经不用Eclipse了,主要原因是查看Jar包中的代码反编译十分不便,项目加载的时候卡,偶尔还会崩溃 用Intellij IDEA和PyCharm 原来的笔记如何在Eclipse ...
-
Week-4-作业1
前言 经过了上周作业的学习拾遗,让我学到了很多东西,也能更好的阅读<构建之法>这本书,下面是我在阅读过第四章和第十七章之后想到的一些问题. 第四章 4.2.1 关于缩进,书中说用四个空格刚 ...
-
[Jobdu] 题目1391:顺时针打印矩阵
题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2 ...
-
C++实现设计模式之 —策略与简单工程结合
策略模式封装算法 // cash.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #inc ...
- Linux6系统安装
-
【lua】LWT HttpdModule
要使用httpd模块,需要在脚本开头添加: require "httpd" httpd.pairs(apr_table) 用以遍历apr_table for key, value ...