Bash 环境变量的那些事

Posted 达内首都教学部

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bash 环境变量的那些事相关的知识,希望对你有一定的参考价值。

BASH环境变量      

bash 变量,尤其是讨厌的环境变量,已经是一个老生常谈的话题了。我们也更应该对它有一个详细的了解,让它为我们所用。

Bash 环境变量的那些事
Bash 环境变量的那些事
下面就打开终端开始吧!


环境变量


Bash 环境变量的那些事

HOME (双关语)除了是你脱下帽子惬意休息的地方,同时也是 Linux 中的一个变量,它是当前用户主目录的路径:


   
     
     
   
  1. echo $HOME


以上这个命令会显示当前用户的主目录路径,通常都在 /home/<your username>  下。


顾名思义,变量的值是可以根据上下文变化的。实际上,Linux 系统中每一个用户的 HOME 变量都是不一样的,当然你也可以这样自行更改 HOME 变量的值:



HOME=/home/<your username>/Documents


以上这个命令将会把 HOME  变量设置为你的  Documents  目录。


其中有三点需要留意:


Bash 环境变量的那些事

=  符号和其两侧的内容之间不加空格。空格在 shell 中有专门的意义,不能随意地在任何地方添加空格。

Bash 环境变量的那些事

如果你需要对变量进行赋值,只需要使用变量名称就可以了。但如果需要读取或者使用变量的值,需要在变量前面加上一个  $  号。

Bash 环境变量的那些事

更改  HOME  变量具有一定的风险。有很多程序是依赖于  HOME  变量的,更改  HOME  变量可能会导致一些不可预见的结果。例如,如果按照上面的方式更改了  HOME  变量,然后执行不带有任何参数的  cd  命令,在通常情况下,会跳转到用户的主目录下,但在这个时候,会跳转到  HOME  变量指定的目录下。


Bash 环境变量的那些事
上面第 3 点中环境变量的更改并不是持久有效的,在终端关闭后重新打开终端,又或者是新建一个终端,执行 echo $HOME 命令输出的仍然会是初始的值,而不是重新自定义的值。
Bash 环境变量的那些事


Bash 环境变量的那些事
在讨论如何持久地更改一个环境变量之前,我们先来看一下另一个比较重要的环境变量。

PATH 变量


Bash 环境变量的那些事

PATH 变量中存放了一系列目录,而且是放置了可执行程序的目录。正是由于 PATH 变量的存在,让你不需要知道应用程序具体安装到了什么目录,而 shell 却可以正确地找到这些应用程序。


如果你查看PATH变量的值,大概会是以下这样:


 

$ echo $PATH

 

/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin


Bash 环境变量的那些事
Bash 环境变量的那些事
每两个目录之间使用冒号: 分隔。如果某个应用程序的所在目录不在 PATH 变量中,那么运行的时候就需要声明应用程序的目录让 shell 能够找到。
Bash 环境变量的那些事

/home/<user name>/bin/my_program.sh

例如以上命令就会执行当前用户bin/ 目录下的 my_program.sh 文件。

有一个常见的问题:如果你不希望弄乱系统的bin/ 目录,同时也不希望你自己的文件被其它人运行,还不想每次运行的时候都要输入完整的路径,那么:

Bash 环境变量的那些事


你可以在你的主目录中创建一个独立的bin/目录:

   
     
     
   
  1. mkdir $HOME/bin

然后将这个目录添加到PATH变量中:

   
     
     
   
  1. PATH=$PATH:$HOME/bin

然后/home/<user name>/bin/ 目录就会出现在 PATH 变量中了。但正如之前所说,这个变更只会在当前的 shell 生效,当前的 shell 一旦关闭,环境变量的值就又恢复原状了。


Bash 环境变量的那些事

如果要让变更对当前用户持续生效,就不能在 shell 中直接执行对应的变更,而是应该将这些变更操作写在每次启动 shell 时都会运行的文件当中。这个文件就是当前用户主目录中的 .bashrc文件。文件名前面的点号表明这是一个隐藏文件,执行普通的ls 命令是不会将这个文件显示出来的,但只要在 ls 命令中加入 -a 参数就可以看到这个文件了。

你可以使用诸如kate[1]gedit[2]nano[3] 或者 vim[4] 这些文本编辑器来打开 .bashrc 文件(但不要用 LibreOffice Writer,它是一个文字处理软件,跟前面几个文字编辑器完全不同)。打开 .bashrc 文件之后,你会看见里面放置了一些 shell 命令,是用于为当前用户设置环境的。


在文件的末尾添加新行病输入一下内容:


   
     
     
   
  1. export PATH=$PATH:$HOME/bin

保存并关闭 .bashrc 文件,接下来你就会看到 export 语句的效果。

执行以下的命令让刚才的修改立即生效:

   
     
     
   
  1. source .bashrc


刚才执行的source 命令让 .bashrc 文件在当前的 shell 立即生效,并且对于之后打开的 shell 都会有效。因此另一个等效的方法是退出并重新进入 shell,但这样也太麻烦了。

现在,你的 shell 就能自动寻找到 /home/<user name>/bin/ 下的程序了,执行这个目录下的程序也不需要完整地写出程序的路径。



自定义变量

当然,你也可以定义自己的变量。刚才我们看到的变量名称都是全大写的,实际上变量名称的定义还是比较灵活的[5]

Bash 环境变量的那些事
定义新变量的过程非常直观,直接对它赋值就可以了:
   
     
     
   
  1. new_variable="Hello"

然后可以用以下的方式读取到已定义变量的值:
   
     
     
   
  1. echo $new_variable


程序的正常工作离不开各种变量,例如要将某个选项设置为打开,又或者让程序找到所需的代码库,都需要使用变量。在 bash 中运行程序的时候会生成一个子 shell,这个子 shell 和执行原程序的父 shell 并不是完全一样的,只是继承了父 shell 的部分内容,而且默认是不继承父 shell 中的变量的。因为变量默认情况下是局部变量,出于安全原因,一个 shell 中的局部变量不会被另一个 shell 读取到,即使是子 shell 也不可以。

Bash 环境变量的那些事

首先定义一个变量:

    
      
      
    
  1. robots="R2D2 & C3PO"

然后执行:

    
      
      
    
  1. bash

现在是在 bash shell 中创建了一个子 shell。

执行这个命令看看还能不能读取到刚才定义的变量:

    
      
      
    
  1. echo $robots

你会发现读取不到。

还是在这个子 shell 中,为 robots 变量赋一个不同的值:

    
      
      
    
  1. robots="These aren't the ones you are looking for"

再读取一次:

    
      
      
    
  1. $ echo $robots

  2. These aren't the ones you are looking for

退出这个子 shell:

    
      
      
    
  1. exit

然后再看一下现在 robots 变量的值:

    
      
      
    
  1. $ echo $robots

  2. R2D2 & C3P0

这一个特性可以有效避免配置过程中产生混乱,同时也会导致一个问题:如果程序中需要设置变量,但却由于子 shell 的原因无法正常访问到这个变量,该如何解决呢?这个时候就需要用到 export 了。


重复一次刚才的过程,但这一次不是通过 robots="R2D2 & C3PO" 方式来设置变量,而是使用 export 命令:

    
      
      
    
  1. export robots="R2D2 & C3PO"

现在你会发现,在进入子 shell 之后,robots 变量的值仍然是最初赋予的值。

要注意的是,尽管子 shell 会继承通过 export 导出的变量,但如果在子 shell 中对这个变量重新赋值,是不会影响到父 shell 中对应变量的。


如果要查看所有通过 export 导出的变量,可以执行以下命令:

    
      
      
    
  1. export -p

自定义的变量会显示在这个列表的末尾。这个列表中还有一些常见的变量:例如 USER 的值是当前用户的用户名,PWD 的值是当前用户当前所在的目录,而 OLDPWD 的值则是当前用户上一个访问过的目录。因此如果执行:

    
      
      
    
  1. cd -

就会切换到上一个访问过的目录,那是因为 cd 命令读取到了 OLDPWD 变量的值。

你也可以使用 env 命令查看所有环境变量。

如果要取消导出一个变量,可以加上 -n 参数:

    
      
      
    
  1. export -n robots

接下来

了解过环境变量的知识之后,你已经到达了可能对自己和他人造成危险的水平,接下来就需要了解如何通过使用别名来让环境变得更安全、更友好以保护自己了。
Bash 环境变量的那些事

命令别名Alias在 Linux shell 中指的是将一些太长或者太难记的多个命令组合起来,成为一个由用户自己构建的命令。

可以通过alias 命令来创建命令别名。在 alias 后面跟上想要创建的别名名称、一个等号(=),以及希望使用这个别名来执行的命令,这样一个命令别名就创建好了。举个例子,ls命令在默认情况下是不会对输出的内容进行着色的,这样就不能让用户一眼分辨出目录、文件和连接了。

Bash 环境变量的那些事

对此,可以创建这样一个命令别名,在输出目录内容的时候为输出内容着色:

alias lc='ls --color=auto'

其中lc 是自定义的命令别名,代表 “list with color” 的意思。在创建命令别名的时候,需要先确认使用的别名是不是已经有对应的命令了,如果有的话,原本的命令就会被覆盖掉了。注意,定义命令别名的时候,= 两端是没有空格的。当运行 lc 的时候,就相当于执行了 ls --color 命令。

此后,执行lc 列出目录内容的时候,就会输出带有着色的内容了。

你可能会发现你在执行ls 的时候,本来就是输出带有着色的内容。那是因为大部分 Linux 发行版都已经将 ls 设定为带有着色的命令别名了。


可以直接使用的命令别名

实际上,执行不带任何内容的alias 命令就可以看到当前已经设定的所有命令别名。对于不同的发行版,包含的命令别名不尽相同,但普遍都会有以下这些命令别名:

Bash 环境变量的那些事


1
◈  alias ls='ls --color=auto':这个命令别名在前面已经提到过了。 --color=auto 参数会让  ls 命令在通过标准输出在终端中显示内容时进行着色,而其它情况(例如通过管道输出到文件)下则不进行着色。 --color 这个参数还可以设置为  always 或 never
2
◈  alias cp='cp -i'-i 参数代表“ 交互interactive”。在使用  cp 命令复制文件的时候,可能会无意中覆盖现有的文件,在使用了  -i 参数之后, cp 命令会在一些关键操作前向用户发出询问。◈  alias free='free -m':在 free 命令后面加上  -m 参数,就可以将输出的内存信息以 MiB 这个更方面阅读和计算的单位输出,而不是默认的 Byte 单位。


你使用的发行版自带的命令别名可能多多少少和上面有些差别。但你都可以在命令前面加上\ 修饰符来使用命令的最基本形式(而不是别名)。例如:

\free

就是直接执行free,而不是free -m。还有:

\ls

执行的就是不带有--color=auto 参数的 ls

如果想要持久地保存命令别名,可以在.bashrc 文件中进行修改,而它来源于我们的 /etc/skel 目录[1]


使用命令别名纠正错误


各种发行版的设计者都会尽量设置用户可能需要用到的命令别名。但是不同的用户的习惯各不相同,一些用户可能刚从其它操作系统迁移到 Linux,而不同操作系统的基本命令又因 shell 而异。因此,对于刚从 Windows/MS-DOS 系统迁移到 Linux 系统的用户,不妨使用




alias dir='ls'


这个命令别名来列出目录内容。

类似地,


alias copy='cp'


alias move='mv'

也可以在尚未完全熟悉 Linux 的时候用得顺手。

有一种情况,就是在经常出现输入错误的场合中做出容错,例如,对于我来说, Administration 这个单词就很难快速正确地输入

因此很多用户都会设置类似这样的别名:

alias sl='ls'

以及

alias gerp='echo "You did it *again*!"; grep'

grep 命令最基本的用途就是在文件中查找字符串,在熟悉这个命令之后,它一定是最常用的命令之一,因此输入错误导致不得不重输命令就很令人抓狂。

在上面gerp 的例子中,包含的不只是一条命令,而是两条。第一条命令 echo "You did it *again*!" 输出了一条提醒用户拼写错误的消息,然后使用分号()把两条命令隔开,再往后才是grep 这一条正确的命令。

Bash 环境变量的那些事

在我的系统上使用gerp 来搜索 /etc/skel/.bashrc 中包含“alias”这个单词的行,就会输出以下内容:

00001. 

$ gerp -R alias /etc/skel/.bashrc


You did it *again*!


       alias ls='ls --color=auto' 


       alias grep='grep --colour=auto' 


       alias egrep='egrep --colour=auto' 


       alias fgrep='fgrep --colour=auto' 


alias cp="cp -i"


alias df='df -h'


alias free='free -m'


alias np='nano -w PKGBUILD' 


alias more=less 


shopt -s expand_aliases


在命令别名中以固定的顺序执行多个命令,甚至更进一步,把多个命令串连起来,让后面的命令可以使用到前面的命令的执行结果。这样的做法已经非常接近 bash 脚本了。如果想要删除在终端中临时设置的别名,可以使用 unalias 命令。


unalias gerp


如果想要持久保存命令别名,可以将命令别名放在用户主目录的.bashrc 文件中。

往期回顾:







以上是关于Bash 环境变量的那些事的主要内容,如果未能解决你的问题,请参考以下文章

iOS-xcconfig环境变量那些事(配置环境的配置)

电脑的环境变量配置那些事!

那年Java那些事 01 — 环境变量和集成开发工具

JS 函数作用域及变量提升那些事!

tomcat那些事

docker镜像那些事!您懂多少?