所有的编程语言都利用变量来存放数据,以备随后使用或修改。和编译型语言不同,大多数脚本语言不要求在创建变量之前声明其类型。用到什么类型就是什么类型。在变量名前面加上一个$符号就可以访问到变量的值。shell定义了一些变量,用于保存用到的配置信息,比如可用的打印机、搜索路径等。这些变量叫作环境变量。
1.3.1 预备知识
变量名由一系列字母、数字和下划线组成,其中不包含空白字符。常用的惯例是在脚本中使用大写字母命名环境变量,使用驼峰命名法或小写字母命名其他变量。
所有的应用程序和脚本都可以访问环境变量。可以使用env或printenv命令查看当前shell
中所定义的全部环境变量:
[root@dev workspace]# envWORKSPACE=/root/workspacePWD=/root/workspaceHOME=/rootGOROOT=/root/go/go1.17.6NAME=MiHomeGOPRIVATE=MAIL=/var/spool/mail/rootSHELL=/bin/bash# …… 其他行
要查看其他进程的环境变量,可以使用如下命令:
cat /proc/$PID/environ[root@dev workspace]# ls /proc1 buddyinfo cpuinfo execdomains irq kpagecgroup meminfo pagetypeinfo stat tty28 bus crypto filesystems kallsyms kpagecount misc partitions swaps uptime7 cgroups devices fs kcore kpageflags modules sched_debug sys version8 cmdline diskstats interrupts keys loadavg mounts schedstat sysvipc vmallocinfo9 config.gz dma iomem key-users locks mtrr self thread-self vmstatacpi consoles driver ioports kmsg mdstat net softirqs timer_list zoneinfo[root@dev workspace]# cat /proc/cpuinfo

其中,PID是相关进程的进程ID(PID是一个整数)。
设有一个叫作gedit的应用程序正在运行。我们可以使用pgrep命令获得gedit的进程ID:
$ pgrep gedit12501
那么,你就可以执行以下命令来查看与该进程相关的环境变量:
$ cat /proc/12501/environGDM_KEYBOARD_LAYOUT=usGNOME_KEYRING_PID=1560USER=slynuxHOME=/home/slynux
注意,实际输出的环境变量远不止这些,只是考虑到页面篇幅的限制,这里删除了不少内容。
特殊文件
/proc/PID/environ是一个包含环境变量以及对应变量值的列表。每一个变量以name=value的形式来描述,彼此之间由null字符(\0)分隔。形式上确实不太易读。
要想生成一份易读的报表,可以将cat命令的输出通过管道传给tr,将其中的\0替换成\n:
$ cat /proc/12501/environ | tr '\0' '\n'
1.3.2 实战演练
可以使用等号操作符为变量赋值:
varName=value
varName是变量名,value是赋给变量的值。如果value不包含任何空白字符(例如空格),那么就不需要将其放入引号中,否则必须使用单引号或双引号。
注意,
var = value不同于var=value。把var=value写成var = value是一个常见的错误。两边没有空格的等号是赋值操作符,加上空格的等号表示的是等量关系测试。
在变量名之前加上美元符号($)就可以访问变量的内容。
[root@dev workspace]# var="value" #将"value"赋给变量var[root@dev workspace]# echo $varvalue[root@dev workspace]#
也可以这样写:
[root@dev workspace]# var="value" #将"value"赋给变量var[root@dev workspace]# echo ${var}value[root@dev workspace]#
输出如下:
value
我们可以在printf、echo或其他命令的双引号中引用变量值:
#!/bin/bash#文件名:variables.shfruit=applecount=5echo "We have $count ${fruit}(s)"
#!/bin/bash[root@dev workspace]# vi variables.sh[root@dev workspace]# chmod +x variables.sh[root@dev workspace]# ./variables.shWe have 5 apple(s)[root@dev workspace]#
输出如下:
We have 5 apple(s)
因为shell使用空白字符来分隔单词,所以我们需要加上一对花括号来告诉shell这里的变量名是fruit,而不是fruit(s)。
环境变量是从父进程中继承而来的变量。例如环境变量HTTP_PROXY,它定义了Internet连接应该使用哪个代理服务器。
该环境变量通常被设置成:
HTTP_PROXY=192.168.1.23:3128export HTTP_PROXY
export命令声明了将由子进程所继承的一个或多个变量。这些变量被导出后,当前shell脚本所执行的任何应用程序都会获得这个变量。shell创建并用到了很多标准环境变量,我们也可以导出自己的环境变量。
例如,PATH变量列出了一系列可供shell搜索特定应用程序的目录。一个典型的PATH变量包含如下内容:
[root@dev workspace]# echo $PATH/root/go/go1.17.6/bin:/root/workspace/golang/bin:/usr/local/libexec/git-core:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib
各目录路径之间以:分隔。$PATH通常定义在/etc/environment、/etc/profile或~/.bashrc中。
如果需要在PATH中添加一条新路径,可以使用如下命令:
export PATH="$PATH:/home/user/bin"
也可以使用
PATH="$PATH:/home/user/bin"export PATHecho $PATH/home/slynux/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/user/bin
这样,我们就将/home/user/bin添加到了PATH中。
另外还有一些众所周知的环境变量:HOME、PWD、USER、UID、SHELL等。
使用单引号时,变量不会被扩展(
expand),仍依照原样显示。这意味着$echo '$var'会显示$var。但如果变量
$var已经定义过,那么$ echo "$var"会显示出该变量的值;如果没有定义过,则什么都不显示。
1.3.3 补充内容
shell还有很多内建特性。下面就是其中一些。
获得字符串的长度
可以用下面的方法获得变量值的长度:
[root@dev workspace]# var="value" #将"value"赋给变量var[root@dev workspace]# echo length=${#var}length=5[root@dev workspace]#
考虑这个例子:
[root@dev workspace]# var=12345678901234567890;echo ${#var}20[root@dev workspace]#
length就是字符串所包含的字符数。
识别当前所使用的 shell
可以通过环境变量SHELL获知当前使用的是哪种shell:
[root@dev workspace]# echo $SHELL/bin/bash
也可以用
[root@dev workspace]# echo $0-bash
检查是否为超级用户
环境变量UID中保存的是用户ID。它可以用于检查当前脚本是以root用户还是以普通用户的身份运行的。例如:
if [ $UID -ne 0 ]thenecho "Non root user. Please run as root."elseecho "Root user"fi

注意,[实际上是一个命令,必须将其与剩余的字符串用空格隔开。上面的脚本也可以写成:
if test $UID -ne 0:1thenecho "Non root user. Please run as root."elseecho "Root user"fi

root用户的UID是0。
修改 Bash 的提示字符串(username@hostname:~$)
当我们打开终端或是运行shell时,会看到类似于user@hostname:/home/$的提示字符串。
不同的GNU/Linux发布版中的提示字符串及颜色各不相同。我们可以利用PS1环境变量来定义主
提示字符串。默认的提示字符串是在文件~/.bashrc中的某一行设置的。
查看设置变量
PS1的那一行:[root@dev workspace]# cat ~/.bashrc | grep PS1export PS1='[\u@dev \W]\$ ' # 默认的 PS1 设置会展示全部的路径,为了防止过长,这里只展示:"用户名@dev 最后的目录名"[root@dev workspace]#
如果要修改提示字符串,可以输入:
lynux@localhost: ~$ PS1="PROMPT>" #提示字符串已经改变PROMPT> Type commands here.
我们可以利用类似于
\e[1;31的特定转义序列来设置彩色的提示字符串(参考 1.2 节的内容)。
还有一些特殊的字符可以扩展成系统参数。例如:\u可以扩展为用户名,\h可以扩展为主机名,而\w可以扩展为当前工作目录。
