每日一Shell(2) 变量和环境变量

一、关于变量

在 bash 里面,变量直接赋值即可使用,每一个变量值都是字符串。

有一些特殊的变量会被 shell 环境和操作系统环境用到,叫做环境变量

查看进程的环境变量

cat /proc/$PID/environ

其中 $PID 是进程的编号(总是一个整数),就可以看到所有环境变量。

默认的输出格式是 key=val,不同的变量之间用 \0 分割,因此如果要换行输出,通过管道用 tr 命令将 \0 替换成 \n 即可:

cat /proc/$PID/environ | tr '\0' '\n'

得到格式如下的输出:

$ cat /proc/1744/environ | tr '\0' '\n'
LANGUAGE=zh_CN:zh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=zh_CN.UTF-8
PWD=/
PHP_FCGI_CHILDREN=32

变量的赋值

a=val

注意等号两边不能有空白字符,后面的内容加不加引号都会被视作字符串。

使用变量的值

echo $a

使用变量的值的时候,需要在变量名前面加上 $,或者加上花括号,形如:${a}

printfecho 中,可以使用 $ 符号引用变量值:

echo "当前的用户是:${USER}"

环境变量的来源和设置

环境变量是未在当前进程中定义,而从父进程中继承而来的变量,例如:

HTTP_PROXY=127.0.0.1:1080
export HTTP_PROXY

export 命令用来设置环境变量,此后,从当前 shell 脚本执行的任何应用程序都会继承这个变量。

例如:$PATH 这个标准的环境变量,我们可以通过如下方式来将一个路径加入到 PATH

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

或者写成:

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

常用的环境变量还有:HOME / PWD / USER / UID / SHELL 等。

单引号里面的 $ 字符不会被解析。不用单引号的时候,如果要输出 $ 字符需要 \$ 转义。

如果变量 var 存在,echo "$var" 会打印该变量的值,否则什么都不打印。

二、变量的一些运算

1. 获取字符串的长度:
length=${#var}
2. 获得当前使用的 SHELL
echo $SHELL
echo $0

其中 $0 意味着执行程序的第一个参数,也就是程序名,即当前的 SHELL(如果在脚本上运行,获得的可能是脚本名称)。

3. 检查是否为超级用户

超级用户 root 的 UID 为 0

if [ $UID -ne 0 ]; then
    echo Non root user. Please run as root.
else
    echo Root user
fi
4. 修改 Bash 提示字符串(username@hostname:~$)

修改 PS1 环境变量并且加到 ~/.bashrc 即可,注意可以使用代码着色:

PS1=prompt>

另外,PS1 环境变量里面的 \u 代表当前用户,\h 代表主机名,’\w` 代表当前目录,这些用法都可以尝试使用。

另外参照这篇文章可以了解更详细的定制用法,参数等:http://www.ibm.com/developerworks/linux/library/l-tip-prompt/

三、路径环境变量

注意 PATHLD_LIBRARY_PATH 这两个环境变量,他们是一系列目录,用 : 分隔的字符串。

然后 shell 需要执行文件的时候,会按次序地在 $PATH 的目录下面查找是否存在该可执行文件。

于是,我们安装一个程序的时候,就需要将程序的执行文件目录加入 $PATH,将其库目录加入 $LD_LIBRARY_PATH

一般是这样写的:

export PATH=/opt/myapp/bin:$PATH
export LD_LIBRARY_PATH=/opt/myapp/lib:$LD_LIBRARY_PATH

然后我们可以定义一个函数来完成这个工作:

prepend() { [ -d $2 ] && eval $1=\"$2:\$$1\" && export $1; }

prepend PATH /opt/myapp/bin
prepend LD_LIBRARY_PATH /opt/myapp/lib

上述函数名称为 prepend$1 为第一个传入的参数,为 PATH 或者 LD_LIBRARY_PATH$2 为第二个传入的参数,为需要添加的路径。

首先判断 $2 路径是否为目录,如果是,则构造一个 export 语句执行。

注意:如果 $1 原始值为空的时候,会多了一个冒号,这个时候,我们可以用下面这种语法:

${parameter:+expression}

这个时候如果 parameter 值存在且非空,就会输出 expression 的值。

那么我们可以修改我们的 prepend 函数来处理原始变量值为空的情况:

prepend() { [ -d $2 ] && eval export $1=$2$\{$1:+:\$$1\} ; }

四、数学运算

1. let 命令(直接执行基本算术操作)

a=4;
b=5
let result=a+b
echo $result  # 输出 9
let a++  # a 变为 5
echo $a  # 输出 5
let --b  # b 变为 4
let a+=b  # 简写形式

let 命令里,可以使用基本的数学运算符,命令中的变量引用全部不用加 $

2. 使用 [] 运算符

result = $[ a + b ]
result = $[ $a + 5 ]

注意到,在 [] 运算符内部可以使用 $ 符号也可以不用。

3. 使用 (())

result=$(( a + 50 ))
echo $(( b - $a ))

用法和 [] 基本一样。

以上三种方法都是整形运算,还支持 &|^% 等运算及位运算,但不支持浮点。

4. bc 命令

bc 命令获取输入流作为输入,支持浮点运算:

基本使用:
echo "4 * 0.56" | bc  # 2.24

no=54;
result=`echo "$no * 1.5"` | bc
echo $result  # 81.0
设定小数精度

注意多句用分号隔开。

echo "scale=2;3/8" | bc  # 0.37
进制转换
no=100
echo "obase=2;$no" | bc  # 1100100
no=1100100
echo "obase=10;ibase=2;$no" | bc  # 100
平方以及平方根
echo "10^2" | bc
echo "sqrt(100)" | bc

具体请参照文档。


【转载请附】愿以此功德,回向 >>

原文链接:https://www.huangwenchao.com.cn/2015/11/bash-shell-2.html【每日一Shell(2) 变量和环境变量】

发表评论

电子邮件地址不会被公开。 必填项已用*标注