变量是 Shell 运行环境中不可或缺的一部分,一些跟 Shell 息息相关的配置或信息都以变量的形式保存在 Shell 运行环境中,比如我们通过 Shell 在不同目录之间来回切换,当前目录的绝对路径将被保存在一个 Shell 变量当中,执行 pwd 命令获取当前路径时,调用该变量的值将被调用。类似的变量还有很多,下面就让我们一起来详细了解一下。
一、变量介绍
跟编程语言中的变量类似,这里的变量是一段有名字的连续存储空间,Shell 或者由 Shell 运行的程序通过变量的名字来使用这段存储空间,依赖各种变量的值作为自身运行的配置,或将运行过程中动态变化的值更新到这些变量之中。引用变量的最大好处就是方便,比如某个应用程序支持多国语言,为了将默认语言与系统保持一致,便可以通过获取变量 LANGUAGE 的值来确定当前系统所使用的语言。
1、变量的可变性
同一个名字的变量,其指向的值可能随着所处环境的不同而变化,这便是 Shell 变量的可变性。举例来说,我们不带参数执行 cd 命令便可以切换到自己的家目录,不带参数的 cd 命令默认进入的是变量 HOME 所指向的路径。当用户 trevor 登陆时,他所打开的 Shell 将拥有 HOME 这个变量,其内容是家目录 /home/trevor ;当用户 town 登陆时,他打开的 Shell 也将拥有 HOME 变量,其内容是家目录 /home/town 。当不同的用户不带参数执行 cd 命令时,cd 命令通过获取 HOME 变量所指向的路径就能自动进入自己的家目录了。这样一来,编写形如 cd 命令这样的程序就显得格外方便了。
2、变量的方便性
如下图所示,由于系统已经帮我们维护了 HOME 变量,所以用户只需要知道 cd 命令的使用方法即可,cd 命令会主动地调用 HOME 变量所指向的值,就能自动进入用户自己的家目录了。
倘若 cd 命令不依靠 HOME 变量来获取用户家目录的路径,而是将路径直接写入程序代码中,那么显然有多少个用户需要少个 cd 命令,造成了资源的浪费,由此可见 Shell 变量的方便性。
二、环境变量
所谓环境变量,一般是指在操作系统中用来指定系统运行环境的变量,比如系统默认语言、用户名、家目录、命令存放路径等。以环境变量 PATH 为例,借助 PATH ,不论我们当前处理哪个目录下执行 cd 命令,系统都能找到它,因为环境变量 PATH 中记录着命令(如 cd)的存放路径。执行任何一个未指定路径的命令时,系统将去 PATH 路径中查找,找到则执行它,否则将提示形如下所示错误。
trevor@trevor-PC:~$ ipconfig 未找到 'ipconfig' 命令,您要输入的是否是: 命令 'tpconfig' 来自于包 'tpconfig' (universe) 命令 'iwconfig' 来自于包 'wireless-tools' (main) 命令 'ifconfig' 来自于包 'net-tools' (main) ipconfig:找不到命令 trevor@trevor-PC:~$
为了与自定义变量相区别,环境变量通常以大写的字符串来表示。环境变量可以协助我们完成很多功能,包括家目录的更改、命令行提示符的显示、命令的搜索路径等等,下面就让我们一起来了解一下 Shell 底下默认的环境变量吧。查阅 Shell 地下的环境变量,我们可以使用 env 或 export 命令。如下所示。
root@trevor-PC:~# env SHELL=/bin/bash TERM=xterm XDG_SESSION_COOKIE=1c893352b678420b8678b7bb0000000e-1331042823.920337-783889701 OLDPWD=/home/trevor USER=root LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: SUDO_USER=trevor SUDO_UID=1000 USERNAME=root MAIL=/var/mail/root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games PWD=/root LANG=zh_CN.UTF-8 SHLVL=1 SUDO_COMMAND=/bin/su HOME=/root LANGUAGE=zh_CN:zh LOGNAME=root LESSOPEN=| /usr/bin/lesspipe %s SUDO_GID=1000 DISPLAY=:0.0 LESSCLOSE=/usr/bin/lesspipe %s %s COLORTERM=gnome-terminal XAUTHORITY=/var/run/gdm/auth-for-trevor-8TzuCp/database _=/usr/bin/env root@trevor-PC:~#
env 是 environment 的缩写,用于列出当前 Shell 底下所有的环境变量。下面列举出上图中主要的环境变量稍作解释。
SHELL: 当前环境下,使用的 Shell 是哪一个程序 OLDPWD:进入当前目录之前所处的目录,即“cd -”命令回到的目录 USER:当前用户的用户名 LS_COLORS:文件类型的颜色显示标记,不同文件之间用冒号(:)分隔 MAIL:mail 命令收信时读取的信箱文件 PATH:命令的搜索路径,路径与路径之间用冒号(:)分隔 PWD:当前目录的路径名 LANG:当前环境下的字符编码格式 HOME:当前用户的家目录 LANGUAGE:当前环境下的默认语言 _:上次使用的命令或者命令的最后一个参数
如果想单独显示某个环境变量的值,只需要使用 echo 命令,将“$环境变量名”或“${环境变量名}”作为其参数执行即可。如下所示。
trevor@trevor-PC:~/linux$ echo $HOME /home/trevor trevor@trevor-PC:~/linux$ echo $OLDPWD /home/trevor/linux/linux100 trevor@trevor-PC:~/linux$ echo $PWD /home/trevor/linux trevor@trevor-PC:~/linux$ echo ${PWD} /home/trevor/linux trevor@trevor-PC:~/linux$
三、变量设定规则
前面介绍了变量的作用以及如何显示某个变量的内容,那么接下来将尝试如何去设置一个变量。很简单,用等号(=)连接变量与您想要为其赋的值就可以了。如下所示。
trevor@trevor-PC:~$ echo $mytest trevor@trevor-PC:~$ mytest=HelloWorld trevor@trevor-PC:~$ echo $mytest HelloWorld trevor@trevor-PC:~$
因为 mytest 变量尚未被配置,所以显示为空,执行“mytest=HelloWorld”命令以后,Shell 变量中就多了一个名为 mytest、值为 HelloWorld 的变量。
其实,变量的设定很容易因为各种各样的问题而出错,设定变量时需要注意如下规则:
1、变量与变量内容应该以等号(=)来连接,如下所示:
trevor@trevor-PC:~$ mytest=HelloWorld trevor@trevor-PC:~$ echo $mytest HelloWorld
2、等号两边不能直接接空格符,如下为错误:
mytest = HelloWorld mytest=Hello World
3、变量名称只能是英文字母与数字,但开头字符不能是数字,如下为错误:
2mytest=HelloWorld
4、变量内容若有空格符可使用双引号(“)或单引号(‘)将变量内容结合起来,但双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:
trevor@trevor-PC:~$ mytest="Hello $USER" trevor@trevor-PC:~$ echo $mytest Hello trevor
5、单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:
trevor@trevor-PC:~$ mytest='Hello $USER' trevor@trevor-PC:~$ echo $mytest Hello $USER
6、可用反斜杠( \ )将特殊符号(如 [Enter], $, \, 空格符, ‘等)变成一般字符;
7、在一串命令中,倘若需要引用其他命令提供的执行结果,可以使用“`命令`”或 “$(命令)”(“`”是键盘上方数字键 1 左边那个键),例如想要取得内核版本的配置:
trevor@trevor-PC:~$ version=$(uname -r) trevor@trevor-PC:~$ echo $version 2.6.35-22-generic
8、若需要扩增变量内容时,则可用 “$变量名称” 或 ${变量} 累加内容,如下所示:
trevor@trevor-PC:~$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games trevor@trevor-PC:~$ PATH="$PATH":/test trevor@trevor-PC:~$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/test trevor@trevor-PC:~$ PATH=${PATH}:/test2 trevor@trevor-PC:~$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/test:/test2
9、若该变量需要在其他子程序中被引用,则需要以 export 来使变量变成环境变量:
export PATH
10、通常大写字符为系统默认变量,自行配置变量可以使用小写字符 ;
11、取消变量的命令为 unset ,例如取消 mytest 的配置:
unset mytest
四、Shell Script 简介
Script 即脚本,它是一类不需要编译的程序文件,具有类似于程序或命令的可执行的属性,但它并不属于计算机语言的范畴。举个反例,C 语言程序经过编译、链接以后才具备执行属性,所以它不是脚本;Java 语言程序也需要编译生成,因此也不是脚本;而 JavaScript 语言编写的代码不需要编译即可被相应的解释器“解释”执行,所以使用 JavaScript 语言编写的程序文件属于脚本。
所有的脚本有两个共同特点:1、脚本的内容是字面上可以读懂的文本;2、不同的脚本必须由不同的解释器解释执行,而脚本的语法则由解释器的设计者来定义。
Shell Script 是一类可以被 Shell 解释的脚本。Script 的本意是“剧本”,因此,可以想象,脚本文件的结构应该是一个流程,剧本中应该包含不同的角色要表演的动作,Linux 命令其实就是“剧本”中角色的动作。Shell Script 解释器除了能导演这些角色之外,还定义了一些条件判断语法,角色可以根据不同的条件进行表演,这种条件判断的语法就像 C 语言中的 if/else、switch/case 语句,不过具体的使用方法有所差别。下面是一个简单的脚本文件:
#!/bin/bash echo "Hello Bash." #display one message
把以上代码保存为一个文件,命名为 test,文件的扩展名可以任意,但常用 sh 作为扩展名,意思是 Shell,或者干脆不要扩展名,因为 Linux 系统不像 Windows 系统那样在乎扩展名。保存后,执行“chmod a+x test”命令,为 test 文件添加执行权限,然后,就可以在终端运行该脚本了。
以上代码中“#!/bin/bash”这个语句是必须的,并且必须在首行,从而让操作系统选择 Bash 来执行脚本文件。第二行中的 echo 是一个linux命令,#后面是注释,在脚本中可以调用各种 Linux 命令,因此脚本的用途非常广泛,凡是需要按照一定的次序执行多个 Linux 命令的场合都可以使用脚本来完成。
除非注明,文章均为CppLive 编程在线原创,转载请注明出处,谢谢。