1.3 玩转变量和环境变量

变量是任何一种编程语言必不可少的组成部分,用于存放各类数据。脚本语言通常不需要在使用变量之前声明其类型。只需要直接赋值就可以了。在Bash中,每一个变量的值都是字符串。无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。有一些特殊的变量会被shell环境和操作系统环境用来存储一些特别的值,这类变量就被称为环境变量。

让我们来看一些实例。

1.3.1 预备知识

变量采用常见的命名方式进行命名。当一个应用程序执行的时候,它接收一组环境变量。可以使用env命令在终端中查看所有与此终端进程相关的环境变量。对于每个进程,在其运行时的环境变量可以使用下面的命令来查看:

  1. cat /proc/$PID/environ

其中,将PID设置成相关进程的进程ID(PID总是一个整数)。

假设有一个叫做gedit的应用程序正在运行。我们可以使用pgrep命令获得gedit的进程ID:

  1. $ pgrep gedit
  2. 12501

那么,你就可以通过以下命令获得与该进程相关的环境变量:

  1. $ cat /proc/12501/environ
  2. GDM_KEYBOARD_LAYOUT=usGNOME_KEYRING_PID=1560USER=slynuxHOME=/home/slynux

实际包含的环境变量远不止这些,只是出于对页面篇幅的考量,在这里删除了其他很多环境变量。

上面介绍的命令返回一个包含环境变量以及对应变量值的列表。每一个变量以name=value的形式来描述,彼此之间由null字符(\0)分割。如果你将\0替换成\n,那么就可以将输出重新格式化,使得每一行显示一对variable=value。替换可以使用tr命令来实现:

  1. $ cat /proc/12501/environ | tr '\0' '\n'

现在,就让我们看看怎样对变量和环境变量赋值以及怎样使用它们吧。

1.3.2 实战演练

一个变量可以通过以下方式进行赋值:

  1. var=value

var是变量名,value是赋给变量的值。如果value不包含任何空白字符(例如空格),那么它不需要使用引号进行引用,反之,则必须使用单引号或双引号。

注意,var = value不同于var=value。把var=value写成var = value是一个常见的错误,但前者是赋值操作,后者则是相等操作。

在变量名之前加上$前缀就可以打印出变量的内容:

  1. var="value" #给变量var赋值
  2. echo $var

或者

  1. echo ${var}

输出如下:

  1. value

我们可以在printfecho命令的双引号中引用变量值。

  1. #!/bin/bash
  2. #文件名: variables.sh
  3. fruit=apple
  4. count=5
  5. echo "We have $count ${fruit}(s)"

输出如下:

  1. We have 5 apple(s)

环境变量是未在当前进程中定义,而从父进程中继承而来的变量。例如环境变量HTTP_PROXY,它定义了一个Internet连接应该使用哪一个代理服务器。

该环境变量通常被设置成:

  1. HTTP_PROXY=http://192.168.0.2:3128
  2. export HTTP_PROXY

export命令用来设置环境变量。至此之后,从当前shell脚本执行的任何程序都会继承这个变量。我们可以按照自己的需要,在执行的应用程序或者shell脚本中导出特定的变量。在默认情况下,有很多标准环境变量可供shell使用。

PATH就是其中之一。通常,变量PATH包含:

  1. $ echo $PATH
  2.  
  3. /home/slynux/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

在给出所要执行的命令后,shell自动在PATH环境变量所包含的目录列表中(各目录路径之间以冒号分隔)查找对应的可执行文件。PATH通常定义在/etc/environment或/etc/profile或~/.bashrc中。如果需要在PATH中添加一条新路径,可以使用:

  1. export PATH="$PATH:/home/user/bin"

也可以使用

  1. $ PATH="$PATH:/home/user/bin"
  2. $ export PATH
  3.  
  4. $ echo $PATH
  5. /home/slynux/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/user/bin

这样,我们就将/home/user/bin添加到了PATH中。

还有一些众所周知的环境变量:HOMEPWDUSERUIDSHELL等。

1.3.3 补充内容

让我们再多看些有关普通变量和环境变量的技巧。

  • 获得字符串长度

可以用下面的方法获得变量值的长度:

  1. length=${#var}

例如:

  1. $ var=12345678901234567890
  2. $ echo ${#var}
  3. 20

length就是字符串所包含的字符数。

  • 识别当前的shell版本

可以用下面的方法获知当前使用的是哪种shell:

  1. echo $SHELL

也可以用

  1. echo $0

例如:

  1. $ echo $SHELL
  2. /bin/bash
  3.  
  4. $ echo $0
  5. bash
  • 检查是否为超级用户

UID是一个重要的环境变量,可以用于检查当前脚本是以超级用户还是以普通用户的身份运行的。例如:

  1. if [ $UID -ne 0 ]; then
  2. echo Non root user. Please run as root.
  3. else
  4. echo "Root user"
  5. fi

root用户的UID是0。

  • 修改Bash提示字符串(username@hostname:~$

当我们打开一个终端或是运行一个shell,都会看到类似于user@hostname: /home/$的提示字符串。不同GNU/Linux发布版中的提示及颜色也略有不同。我们可以利用PS1环境变量来定制提示文本。默认的shell提示文本是在文件~/.bashrc中的某一行设置的。

  • 可以使用如下命令列出设置PS1的那一行:
  1. $ cat ~/.bashrc | grep PS1
  2. PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
  • 如果要设置提示字符串,可以输入:
  1. slynux@localhost: ~$ PS1="PROMPT>"
  2. PROMPT> Type commands here # 提示字符串已经改变
  • 我们可以利用类似\e[1;31的特定转义序列来设置彩色的提示字符串(参考1.2节的内容)。

还有一些特殊的字符可以扩展成系统参数。例如:\u可以扩展为用户名,\h可以扩展为主机名,而\w可以扩展为当前工作目录。