和编译型语言不同,大多数脚本语言不要求在创建变量之前声明其类型,用到什么类型就是什么类型。在变量名前面加上一个美元符号就可以访问到变量的值
预备知识
变量名:由一系列字母、数字和下划线组成,其中不包含空白字符。常用的惯例是在脚本中使用大写字母命名环境变量,使用驼峰命名法或小写字母命名其它变量
所有的应用程序和脚本都可以访问环境变量
可以使用env
或printenv
命令查看当前shell中所定义的全部环境变量
$> env
PWD=/home/clif/ShellCookBook
HOME=/home/clif
SHELL=/bin/bash
# ......
要查看其它进程的环境变量
cat /proc/$PID/environ
其中,PID是相关进程的进程ID(PID是一个整数)
可以用pgrep
命令获得进程的进程ID
$ pgrep gedit
12501
$ cat /proc/12501/environ
# ......
特殊文件/proc/PID/environ是一个包含环境变量以及对应变量值的列表。每一个变量以name=value的形式来描述,彼此之间由null字符(\0)分隔。形式上可能不太易读
$ cat /proc/12501/environ | tr '\0' '\n' # 生成一份易读的报表
使用等号操作符为变量赋值,两边没有空格的等号是赋值操作符,加上空格的等号表示的是等量关系测试
varName=value # 如果value包含空白字符,需要将其放入引号中
在变量名之前加上美元符号($)就可以访问变量的内容
var="value" # 将"value"赋给变量var
echo $var
echo ${var} # 使用花括号界定变量名
可以在printf、echo或其它命令的双引号中引用变量值
#!/bin/bash
# filename:variables.sh
fruit=apple
count=5
echo "We have $count ${fruit}(s)"
# We have 5 apple(s)
环境变量是从父进程中继承而来的变量
HTTP_PROXy=192.168.1.23:3128
export HTTP_PROXY
export命令声明了将由子进程所继承的一个或多个变量
PATH变量列出了一系列可供shell搜索特定应用程序的目录
$ echo $PATH
/home/tl/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/sbin/bin:/bin
各目录路径之间以:分隔,$PATH通常定义在/etc/environment、/etc/profile或~/.bashrc中
以下命令在PATH中添加一条新路径
$ export PATH="$PATH:/home/user/bin"
$ PATH="$PATH:/home/user/bin"
$ export PATH
$ echo $PATH
其它常见环境变量:HOME PWD USER UID SHELL
1. 获得字符串的长度
length=${#var}
2. 识别当前所使用的shell
echo $SHELL
echo $0
# /bin/bash
3. 检查是否为超级用户
if [ $UID -ne 0 ]; then # 注意[]与表达式之间需要有空格
echo Non root user. Please run as root
else
echo Root user
fi
if test $UID -ne 0; then
echo Non root user. Please run as root
else
echo Root user
fi
root用户的UID是0
4. 修改Bash的提示字符串(username@hostname$)
$ cat ~/.bashrc | grep PS1
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$'
\u为用户名,\h为主机名,\w为当前工作目录
使用函数添加环境变量
环境变量通常保存了可用于搜索可执行文件、库文件等的路径列表。例如$PATH和$LD_LIBRARY_PATH
PATH=/usr/bin:/bin # shell执行应用程序(二进制文件或脚本)时,它会首先查找/usr/bin,然后查找/bin
LD_LIBRARY_PATH=/usr/lib:/lib
当使用源代码构建并安装程序时,通常需要为新的可执行文件和库文件添加特定的路径。假设要将myapp安装到/opt/myapp,它的二进制文件在/opt/myapp/bin目录中,库文件在/opt/myapp/lib中
export PATH=/opt/myapp/bin:$PATH
export LD_LIBRARY=/opt/myapp/lib:$LD_LIBRARY_PATH
# 将prepend函数定义在.bashrc文件中
prepend() {[ -d "$2" ] && eval $1=\"$2':'\$$1\" && export $1;}
prepend PATH /opt/myapp/bin
prepend LD_LIBRARY_PATH /opt/myapp/lib
工作原理
函数prepend()首先确认该函数第二个参数所指定的目录是否存在。如果存在,eval表达式将第一个参数所指定的变量值设置成第二个参数的值加上:(路径分隔符),随后再跟上第一个参数的原始值
在进行添加时,如果变量为空,则会在末尾留下一个:。下面为解决方法
prepend() { [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export $1 ; }
shell参数扩展的形式$parameter:+expression
,如果parameter有值且不为空,则使用expression的值