Bash 中 SHLVL 变量为 1000 的时候

时间:2022-09-15 12:40:42

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 的时候的更多相关文章

  1. bash 中的变量

    bash 中的变量 Linux command line 笔记 变量无需声明,自动创建 var=abc #变量a赋值为字符串abc var="hello world" #字符串里有 ...

  2. Bash中的变量

    Bash中的变量1.用户定义的变量变量的定义  用户定义的变量有字母数字及下划线组成,并且变量名的第一个字符不能为数字.            与其它UNIX名字一样,变量名是大小写敏感的. 对于变量 ...

  3. 在Linux系详解Linux bash中的变量

    (大讲台:国内首个it在线教育混合式自适应学习) 统中进行日常运维或者是编写脚本时,变量是再熟悉不过的了,但这些变量都有哪些类型,具体的用法又有哪些差异呢?本文整理分享给大家: 一.bash变量类型: ...

  4. Linux bash中的变量分类

    1.本地变量 VAR=XYZ 2.局部变量 local VAR=XYZ 3.环境变量 在子shell中可以起作用 export VAR=XYZ 4.位置变量 $0 脚本名本身 $1 第一个参数 $2 ...

  5. bash中声明变量方法

    bash提供了declare命令来声明变量,该命令的基本语法如下: declare attribute variable      其中,attribute表示变量的属性,常用的属性有如下所述.   ...

  6. bash 中的变量可以这么用

    举个例子: t.sh ====================== #!/bin/bash ./a.sh ./b.sh ======================= a.sh =========== ...

  7. Bash简明教程--变量

    1. 前言 Bash是一门流行在*nix系统下的脚本语言.作为一门脚本语言,变量是一门语言的基本要素,在这篇教程中,我们将学习Bash中的变量是怎么表示的,以及变量相关的一些语法规则. 2. Bash ...

  8. bash中一些基础知识

    bash是linux操作系统的shell.以下是Multi-Perspective Sentence Similarity Modeling论文实现时碰到的一个bash: #!/bin/bash py ...

  9. (二)shell中的变量

    1.常用系统变量 $HOME.$PWD.$SHELL.$USER等 2.自定义变量 基本语法: (1)定量变量:变量=值 (2)撤销变量:unset 变量 (3)声明静态变量:readonly变量 注 ...

随机推荐

  1. ahjesus sql手动重新更新ID

    declare cus_cursor cursor scroll for SELECT Id from [dbo].[TLotterySpiderRule] open cus_cursor decla ...

  2. Android中UI线程与后台线程交互设计的5种方法

    我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...

  3. java&period;lang&period;NullPointerException错误分析

    java.lang.NullPointerException是什么错误 你使用了空的指针.在java中虽然号称抛弃了C++中不安全的指针,但其实他所有的东西你都可以理解为指针.这种情况一般发生在你使用 ...

  4. 动态的加载显示oracle警告日志文件内容

    Last login: Fri Jan 25 00:37:47 2019 from oracle [root@oracle ~]# su - oracle [oracle@oracle ~]$ sql ...

  5. Windows系统下在Eclipse中集成Python

    我现在偶尔开发代码,已经不用Eclipse了,主要原因是查看Jar包中的代码反编译十分不便,项目加载的时候卡,偶尔还会崩溃 用Intellij IDEA和PyCharm 原来的笔记如何在Eclipse ...

  6. Week-4-作业1

    前言 经过了上周作业的学习拾遗,让我学到了很多东西,也能更好的阅读<构建之法>这本书,下面是我在阅读过第四章和第十七章之后想到的一些问题. 第四章 4.2.1 关于缩进,书中说用四个空格刚 ...

  7. &lbrack;Jobdu&rsqb; 题目1391:顺时针打印矩阵

    题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2 ...

  8. C&plus;&plus;实现设计模式之 —策略与简单工程结合

    策略模式封装算法 // cash.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #inc ...

  9. Linux6系统安装

  10. 【lua】LWT HttpdModule

    要使用httpd模块,需要在脚本开头添加: require "httpd" httpd.pairs(apr_table) 用以遍历apr_table for key, value ...