1. 环境变量概念及分类

bash shell 用一个叫作环境变量(environment variable)的特性来存储有关 shell 会话和工作环境的信息(这也是它们被称作环境变量的原因)。这项特性允许你在内存中存储数据,以便程序或shell 中运行的脚本能够轻松访问到它们。

在bash shell中,环境变量分为两类:

  • 全局变量
  • 局部变量

1.1 全局环境变量

全局环境变量对于 shell 会话和所有生成的子 shell 都是可见的。局部变量则只对创建它们的 shell可见。Linux 系统在你开始 bash 会话时就设置了一些全局环境变量,系统环境变量基本上都是使用全大写字母,以区别于普通用户的环境变量。

要查看全局变量,可以使用 env 或 printenv 命令:

$ printenv
HOSTNAME=server01.class.edu
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
[...]
HOME=/home/Christine
LOGNAME=Christine
[...]
G_BROKEN_FILENAMES=1
_=/usr/bin/printenv

要显示个别环境变量的值,可以使用 printenv 命令,但是不要用 env 命令。

$ printenv HOME
/home/Christine
$
$ env HOME
env: HOME: No such file or directory
$

也可以使用 echo 显示变量的值。在这种情况下引用某个环境变量的时候,必须在变量前面加上一个美元符($)。

$ echo $HOME
/home/Christine
$

1.2 局部环境变量

局部环境变量只能在定义它们的进程中可见,事实上,Linux 系统也默认定义了标准的局部环境变量。不过你也可以定义自己的局部变量,如你所想,这些变量被称为用户定义局部变量。

set 命令会显示为某个特定进程设置的所有环境变量,包括局部变量、全局变量以及用户定义变量。

$ set
BASH=/bin/bash
[...]
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
[...]
colors=/etc/DIR_COLORS
my_variable='Hello World'
[...]
$

注意:命令 env、printenv 和 set 之间的差异很细微。set 命令会显示出全局变量、局部变量以及用户定义变量。它还会按照字母顺序对结果进行排序。env 和 printenv 命令同 set 命令的区别在于前两个命令不会对变量排序,也不会输出局部变量和用户定义变量。

2. 设置自定义变量

2.1 设置局部用户自定义变量

一旦启动了 bash shell(或者执行一个 shell 脚本),就能创建在这个 shell 进程内可见的局部变量了。可以通过等号给环境变量赋值,值可以是数值或字符串。

$ echo $my_variable
$ my_variable=Hello
$
$ echo $my_variable
Hello

如果要给变量赋一个含有空格的字符串值,必须用单引号来界定字符串的首和尾。

$ my_variable=Hello World
-bash: World: command not found
$
$ my_variable="Hello World"
$
$ echo $my_variable
Hello World
$

你定义的局部环境变量用的是小写字母,而到目前为止你所看到的系统环境变量都是大写字母。

注意:所有的环境变量名均使用大写字母,这是 bash shell 的标准惯例。如果是你自己创建的局部变量或是 shell 脚本,请使用小写字母。变量名区分大小写。在涉及用户定义的局部变量时坚持使用小写字母,这能够避免重新定义系统环境变量可能带来的灾难。

记住,变量名、等号和值之间没有空格,这一点非常重要。如果在赋值表达式中加上了空格,bash shell 就会把值当成一个单独的命令:

$ my_variable = "Hello World"
-bash: my_variable: command not found
$

设置了局部环境变量后,就能在 shell 进程的任何地方使用它了。但是,如果生成了另外一个shell,它在子 shell 中就不可用。

$ my_variable="Hello World"
$
$ bash
$
$ echo $my_variable
$ exit
exit
$
$ echo $my_variable
Hello World
$

在这个例子中生成了一个子 shell。在子 shell 中无法使用用户定义变量 my_variable。通过命令echo $my_variable 所返回的空行就能够证明这一点。当你退出子 shell 并回到原来的 shell 时,这个局部环境变量依然可用。

类似地,如果你在子进程中设置了一个局部变量,那么一旦你退出了子进程,那个局部环境变量就不可用。

2.2 设置全局环境变量

在设定全局环境变量的进程所创建的子进程中,该变量都是可见的。创建全局环境变量的方法是先创建一个局部环境变量,然后再把它导出到全局环境中。

  1. 这个过程通过export命令来完成,变量名前面不需要加$。

    $ my_variable="I am Global now"
    $
    $ export my_variable
    $
    $ echo $my_variable
    I am Global now
    $
    $ bash
    $
    $ echo $my_variable
    I am Global now
    $
    $ exit
    exit
    $
    $ echo $my_variable
    I am Global now
    $
    

  2. 修改子shell中全局环境变量并不会影响到父shell中该变量的值。

    $ my_variable="I am Global now"
    $ export my_variable
    $
    $ echo $my_variable
    I am Global now
    $
    $ bash
    $
    $ echo $my_variable
    I am Global now
    $
    $ my_variable="Null"
    $
    $ echo $my_variable
    Null
    $
    $ exit
    exit
    $
    $ echo $my_variable
    I am Global now
    $
    

  3. 子shell甚至无法使用export命令改变父shell中全局环境变量的值。

    $ my_variable="I am Global now"
    $ export my_variable
    $
    $ echo $my_variable
    I am Global now
    $
    $ bash
    $
    $ echo $my_variable
    I am Global now
    $
    $ my_variable="Null"
    $
    $ export my_variable
    $
    $ echo $my_variable
    Null
    $
    $ exit
    exit
    $
    $ echo $my_variable
    I am Global now
    $
    

3. 删除环境变量

既然可以创建新的环境变量,自然也能删除已经存在的环境变量。可以用 unset 命令完成这个操作。在 unset 命令中引用环境变量时,记住不要使用 $。

$ echo $my_variable
I am Global now
$
$ unset my_variable
$
$ echo $my_variable
$
#在涉及环境变量名时,什么时候该使用 $,什么时候不该使用 $,实在让人摸不着头脑。
#记住一点就行了:如果要用到变量,使用 $;如果要操作变量,不使用 $。这条规则的一
#个例外就是使用 printenv 显示某个变量的值。

在处理全局环境变量时,事情就有点棘手了。如果你是在子进程中删除了一个全局环境变量,这只对子进程有效。该全局环境变量在父进程中依然可用。

$ my_variable="I am Global now"
$
$ export my_variable
$
$ echo $my_variable
I am Global now
$
$ bash
$
$ echo $my_variable
I am Global now
$
$ unset my_variable
$
$ echo $my_variable
$ exit
exit
$
$ echo $my_variable
I am Global now
$

和修改变量一样,在子 shell 中删除全局变量后,你无法将效果反映到父 shell 中。

4. 设置 PATH 环境变量

当你在 shell 命令行界面中输入一个外部命令时,shell 必须搜索系统来找到对应的程序。PATH 环境变量定义了用于进行命令和程序查找的目录。

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:
/sbin:/bin:/usr/games:/usr/local/games
$

输出中显示了有 8 个可供 shell 用来查找命令和程序。PATH 中的目录使用冒号分隔。
如果命令或者程序的位置没有包括在 PATH 变量中,那么如果不使用绝对路径的话,shell 是没法找到的。如果 shell 找不到指定的命令或程序,它会产生一个错误信息:

$ myprog
-bash: myprog: command not found
$

问题是,应用程序放置可执行文件的目录常常不在 PATH 环境变量所包含的目录中。解决的办法是保证 PATH 环境变量包含了所有存放应用程序的目录。

可以把新的搜索目录添加到现有的 PATH 环境变量中,无需从头定义。PATH 中各个目录之间是用冒号分隔的。你只需引用原来的 PATH 值,然后再给这个字符串添加新目录就行了。可以参考下面的例子。

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:
/sbin:/bin:/usr/games:/usr/local/games
$
$ PATH=$PATH:/home/christine/Scripts
$
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/
games:/usr/local/games:/home/christine/Scripts
$
$ myprog
The factorial of 5 is 120.
$

对 PATH 变量的修改只能持续到退出或重启系统。这种效果并不能一直持续。

5. 环境变量持久化

对全局环境变量来说(Linux系统中所有用户都需要使用的变量),可能更倾向于将新的或修改过的变量设置放在 /etc/profile 文件中,但这可不是什么好主意。如果你升级了所用的发行版,这个文件也会跟着更新,那你所有定制过的变量设置可就都没有了。

最好是在 /etc/profile.d目录中创建一个以.sh 结尾的文件。把所有新的或修改过的全局环境变量设置放在这个文件中。

在大多数发行版中,存储个人用户永久性 bash shell 变量的地方是 $HOME/.bashrc 文件。这一点适用于所有类型的 shell 进程。但如果设置了 BASH_ENV变量,那么记住,除非它指向的是
$HOME/.bashrc,否则你应该将非交互式 shell 的用户变量放在别的地方。

6. 数组变量

环境变量有一个很酷的特性就是,它们可作为数组使用。

  1. 要给某个环境变量设置多个值,可以把值放在括号里,值与值之间用空格分隔

    $ mytest=(one two three four five)
    $
    
  2. 要引用一个单独的数组元素,就必须用代表它在数组中位置的数值索引值。索引值要用方括号括起来

    $ echo ${mytest[2]}
    three
    $
    
  3. 要显示整个数组变量,可用星号作为通配符放在索引值的位置

    $ echo ${mytest[*]}
    one two three four five
    $
    
  4. 也可以改变某个索引值位置的值

    $ mytest[2]=seven
    $
    $ echo ${mytest[*]}
    one two seven four five
    $
    
  5. 甚至能用 unset 命令删除数组中的某个值,但是要小心,这可能会有点复杂

    $ unset mytest[2]
    $
    $ echo ${mytest[*]}
    one two four five
    $
    $ echo ${mytest[2]}
    $ echo ${mytest[3]}
    four
    $
    

    这个例子用 unset 命令删除在索引值为 2 的位置上的值。显示整个数组时,看起来像是索引里面已经没这个索引了。但当专门显示索引值为 2 的位置上的值时,就能看到这个位置是空的。

  6. 可以在 unset 命令后跟上数组名来删除整个数组

    $ unset mytest
    $
    $ echo ${mytest[*]}
    $
    

Linux shell 学习笔记(4)— linux 环境变量(全局变量、局部变量及变量持久化)相关推荐

  1. Linux shell 学习笔记(7)— 构建基本脚本(变量、重定向、管道、状态码)

    1. 使用多个命令 如果要两个命令一起运行,可以把它们放在同一行中,彼此间用分号隔开. $ date ; who Mon Feb 21 15:36:09 EST 2014 Christine tty2 ...

  2. Linux+javaEE学习笔记之Linux网络环境配置

    Linux+javaEE学习笔记之Linux网络环境配置 网络知识简单介绍: Ip地址是:IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物 ...

  3. linux系统管理学习笔记之一-------linux解压缩命令

    linux系统管理学习笔记之一-------linux解压缩命令 2009-12-29 11:52:55 标签:linux tar [推送到技术圈] 版权声明:原创作品,允许转载,转载时请务必以超链接 ...

  4. linux系统管理学习笔记之八---linux文件与目录的管理及权限

    linux系统管理学习笔记之八---linux文件与目录的管理及权限 2010-01-05 09:00:49 标签:权限 管理 文件目录 linx [推送到技术圈] 版权声明:原创作品,允许转载,转载 ...

  5. linux shell学习笔记(二) 变量和运算符

    1.什么是shell变量?本地变量.环境变量.变量替换(显示变量).位置变量.标准变量.特殊变量.影响变量的命令 2.本地变量:本地变量在用户现在的shell生命期的脚本中使用 variable-na ...

  6. Linux shell 学习笔记(10)— 处理用户输入(命令行读取参数、读取用户输入、超时处理)

    1. 命令行参数 向 shell 脚本传递数据的最基本方法是使用命令行参数.命令行参数允许在运行脚本时向命令行添加数据. $ ./addem 10 30 本例向脚本 addem 传递了两个命令行参数( ...

  7. 【Linux】Linux Shell 学习笔记:什么是Linux?

    I Linux 简介 Linux系统简介 (biancheng.net) Linux和UNIX的关系及区别 (biancheng.net) Linux内核_百度百科 (baidu.com) [什么是 ...

  8. linux shell 学习笔记

    shell中定义变量形式: yourname='tengxi' 注意等号两边不能有空格,否则会报语法错误 使用变量 echo $yourname 或者 echo ${yourname}(推荐带花括号的 ...

  9. Linux shell 学习笔记(12)— linux 信号、后台运行脚本、作业控制、定时运行任务

    1. 处理信号 1.1 Linux 信号 常见的 Linux 信号如下表所示: 信号 值 描述 1 SIGHUP 挂起进程 2 SIGINT 终止进程 3 SIGQUIT 停止进程 9 SIGKILL ...

最新文章

  1. codevs1245 最小的N个和
  2. 一元三次方程求解matlab_初中数学最全函数/方程【实际应用题】分类详解提升必学必练!...
  3. Pyramid Attention Network for Semantic Segmentation
  4. LeetCode题解——Palindrome Number
  5. response Headers与request Headers字段详解(收藏)
  6. 兄弟连php课件,兄弟连php课件
  7. 关于SO、SOP、SOIC封装(宽体、中体、窄体)的详解
  8. 利用matlab实现AM调制解调
  9. dsp6657的helloworld例程测试-第二篇-CFG文件
  10. 通过耳机口左右声道输出得到4路控制信号
  11. python:微信支付链接转化成图片(data格式、PNG格式)
  12. 标志设计中选择合适的字体
  13. 国内各类 WebShell 密码大全 爆破、社工用 webshell-password
  14. 贪心算法(最优装载问题,田忌赛马,雷达问题)
  15. Redis源码分析 —— 发布与订阅
  16. DWZ富客户端框架使用手册
  17. Linux之离线安装Ganglia
  18. 使用Java实现Comet风格的Web应用(二)
  19. 浏览器--搜索操作符15个实例
  20. 安卓基本的POST请求工具类

热门文章

  1. 2022-2028年中国冶金工业节能减排投资分析及前景预测报告
  2. lisp协议instand_分享|Linux 上 10 个最好的 Markdown 编辑器
  3. VS Code 离线安装插件方法
  4. 解决git本地提交不到远程库
  5. 实践学习:首次项目合作
  6. 数组的拼接合并 numpy
  7. Pytorch实现MNIST(附SGD、Adam、AdaBound不同优化器下的训练比较) adabound实现
  8. 在C++中加载TorchScript模型
  9. TensorRT 7.2.1开发初步
  10. 自然语言推理和数据集