一、变量类型

分为环境变量(全局变量)和普通变量(局部变量)

1.1 环境变量

用于定义shell运行环境,保证shell命令正确执行.一般是用export内置命令导出的变量.
环境变量可以在命令中设置和创建,用户退出命令行这些变量值会丢失.希望永久保存环境
变量可在用户家目录下的.bash_profile 或者.bashrc文件中保存.或者在全局配置/etc/bashrc或者/etc/profile文件中定义.定义好后用户每次登录这些变量都会被初始化.

部分bash环境变量如下表


三个命令显示变量的值set env declare
set命令输出所有变量(局部变量和全局变量)-o 显示bash shell所有参数配置信息。
env命令只显示全局变量
declare命令输出所有变量、函数、整数和已经导出的变量

1.1.1、自定义变量和取消

以https_proxy为例
自定义:
eg:export https_proxy=http://192.168.10.20:1087
或者
declare -x https_proxy=http://192.168.10.20:1087
取消:
unset https_proxy
显示:
echo $https_proxy

1.1.2 环境变量初始化

系统登录bash shell时会查找到环境变量设置文件,这些文件叫环境文件。检查环境变量文件情况取决于系统运行shell的方式。
运行方式一般有下面三种:
1)通过系统用户登录后默认运行的shell。
2)非登录交互运行shell
3)执行脚本运行非交互式shell
第一种用户登录运行shell加载文件如图:

加载完上图后开始加载$HOME/.bashrc(用户环境变量文件),并去找/etc/bashrc(全局环境变量文件),都是有就执行,没有不执行。
如果用户的shell不是登录启动,非登录shell只会加载$HOME/.bashrc(用户环境变量文件),并去找/etc/bashrc(全局环境变量文件),都是有就执行,没有不执行。

二、普通变量

2.1定义本地变量

变量赋值:
a=1
a='1'
a="1"
引号的含义
不加引号原样输出,有变量解析变量输出
单引号,按引号内字符输出,有变量也不会解析
双引号和没引号情况一致,有变量和命令都会解析后输出。
注意:数字一般不加引号,字符串通常双引号,原样输出单引号。

把命令结果赋值给变量:
a=`ifconfig`
a=$(ifconfig)


三、 shell变量进阶

3.1 shell 中特殊且重要的变量

命令行、函数、或脚本执行等传参数会用到一些位置参数变量,例如$0$1、 $#等称为特殊位置参数变量。
说明如下:


获取脚本执行进程号双$
示范:

root@ubuntu10112:/opt/shelltest# vim echovar.sh 
echo "This shell is:$0"
echo "This shell var have:$#"
echo "They are :$*"
echo have '"$*"':"$*"
echo "They are :$@"
echo have '"$@"':"$@"
root@ubuntu10112:/opt/shelltest# bash /opt/shelltest/echovar.sh {1..15}
This shell is:/opt/shelltest/echovar.sh
This shell var have:15
They are :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
have "$*":1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
They are :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
have "$@":1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
root@ubuntu10112:/opt/shelltest# bash /opt/shelltest/echovar.sh {a..z} 
This shell is:/opt/shelltest/echovar.sh
This shell var have:26
They are :a b c d e f g h i j k l m n o p q r s t u v w x y z
have "$*":a b c d e f g h i j k l m n o p q r s t u v w x y z
They are :a b c d e f g h i j k l m n o p q r s t u v w x y z
have "$@":a b c d e f g h i j k l m n o p q r s t u v w x y z

上面不太好看出$*$# 区别,那么看下面例子:

root@ubuntu10112:/opt/shelltest# set -- 5 "20" 13 14 "You are" my Love
root@ubuntu10112:/opt/shelltest# echo $#
7
root@ubuntu10112:/opt/shelltest# for i in $*;do echo $i;done             
5
20
13
14
You
are
my
Love
root@ubuntu10112:/opt/shelltest# for i in "$*";do echo $i;done
5 20 13 14 You are my Love
root@ubuntu10112:/opt/shelltest# for i in $@;do echo $i;done   
5
20
13
14
You
are
my
Love
root@ubuntu10112:/opt/shelltest# for i in "$@";do echo $i;done
5
20
13
14
You are
my
Love

3.3 变量子串

3.3.1 变量子串说明:


3.3.2 获取变量长度 三种方法:

echo  ${#变量名}
echo $变量  | wc -l
echo  "$变量" | awk '{print length($0)}'

3.3.3 变量截取和匹配例子:

root@ubuntu10112:/opt/shelltest# k="abcABC123ABCabc"
root@ubuntu10112:/opt/shelltest# echo ${k}
abcABC123ABCabc
root@ubuntu10112:/opt/shelltest# echo ${k:2}
cABC123ABCabc
root@ubuntu10112:/opt/shelltest# echo ${k:2:2}
cA
root@ubuntu10112:/opt/shelltest# echo ${k:2:3}
cAB
root@ubuntu10112:/opt/shelltest# echo ${k} | cut -c 2-3
bc
root@ubuntu10112:/opt/shelltest# echo $k
abcABC123ABCabc
root@ubuntu10112:/opt/shelltest# echo ${k#a*C}         
123ABCabc
root@ubuntu10112:/opt/shelltest# echo ${k#a*c} 
ABC123ABCabc
root@ubuntu10112:/opt/shelltest# echo ${k##a*c}

root@ubuntu10112:/opt/shelltest# echo ${k##a*C}
abc
root@ubuntu10112:/opt/shelltest# echo ${k%a*C} 
abcABC123ABCabc
root@ubuntu10112:/opt/shelltest# echo ${k%a*c}
abcABC123ABC
root@ubuntu10112:/opt/shelltest# echo ${k%%a*c}

root@ubuntu10112:/opt/shelltest# echo ${k%%a*C}
abcABC123ABCabc
root@ubuntu10112:/opt/shelltest# 

3.3.4 变量字符串替换

root@ubuntu10112:/opt/shelltest# d="Be slow to promise and quick to perform."
root@ubuntu10112:/opt/shelltest# echo $d
Be slow to promise and quick to perform.
root@ubuntu10112:/opt/shelltest# echo ${d/to/too}
Be slow too promise and quick to perform.
root@ubuntu10112:/opt/shelltest# echo ${d//to/too}
Be slow too promise and quick too perform.


应用案例:
下面是一个利用子串替换方法批量重命名文件例子

root@ubuntu10112:/opt/shelltest/rename# for i in kv{1..15}text.log ; do touch $i;done
root@ubuntu10112:/opt/shelltest/rename# ls
kv10text.log  kv12text.log  kv14text.log  kv1text.log  kv3text.log  kv5text.log  kv7text.log  kv9text.log
kv11text.log  kv13text.log  kv15text.log  kv2text.log  kv4text.log  kv6text.log  kv8text.log
root@ubuntu10112:/opt/shelltest/rename# g=kv15text.log
root@ubuntu10112:/opt/shelltest/rename# echo ${g//text/typt}
kv15typt.log
root@ubuntu10112:/opt/shelltest/rename# echo ${g//text/type}
kv15type.log
root@ubuntu10112:/opt/shelltest/rename# mv $g ${g//text/type}
root@ubuntu10112:/opt/shelltest/rename# ls
kv10text.log  kv12text.log  kv14text.log  kv1text.log  kv3text.log  kv5text.log  kv7text.log  kv9text.log
kv11text.log  kv13text.log  kv15type.log  kv2text.log  kv4text.log  kv6text.log  kv8text.log
root@ubuntu10112:/opt/shelltest/rename# ls *text*.log
kv10text.log  kv12text.log  kv14text.log  kv2text.log  kv4text.log  kv6text.log  kv8text.log
kv11text.log  kv13text.log  kv1text.log   kv3text.log  kv5text.log  kv7text.log  kv9text.log
root@ubuntu10112:/opt/shelltest/rename# for j in $(ls *text*.log);do mv $j $(echo ${j//text/type});done
root@ubuntu10112:/opt/shelltest/rename# ls
kv10type.log  kv12type.log  kv14type.log  kv1type.log  kv3type.log  kv5type.log  kv7type.log  kv9type.log
kv11type.log  kv13type.log  kv15type.log  kv2type.log  kv4type.log  kv6type.log  kv8type.log
root@ubuntu10112:/opt/shelltest/rename# 

3.4 shell 特殊扩展变量介绍

特殊扩展变量如下:

每个表达式的冒号可选,如果冒号省略,代表每个定义中为空或者未赋值部分改为未赋值,就是说运算符只是用来测试变量是否未赋值。
实测如下:

root@ubuntu10112:/opt/shelltest# echo $test

root@ubuntu10112:/opt/shelltest# result=${test:-UNSET}
root@ubuntu10112:/opt/shelltest# echo $result
UNSET
root@ubuntu10112:/opt/shelltest# echo $test

root@ubuntu10112:/opt/shelltest# test=hahaha
root@ubuntu10112:/opt/shelltest# echo $test
hahaha
root@ubuntu10112:/opt/shelltest# result=${test:-UNSET}
root@ubuntu10112:/opt/shelltest# echo $result
hahaha
root@ubuntu10112:/opt/shelltest# unset result
oot@ubuntu10112:/opt/shelltest# result=${test:=UNSET}
root@ubuntu10112:/opt/shelltest# echo $test
UNSET
root@ubuntu10112:/opt/shelltest# echo $result
UNSET
root@ubuntu10112:/opt/shelltest# echo ${key:?NOT DEFINED}
-bash: key: NOT DEFINED
root@ubuntu10112:/opt/shelltest# echo ${key?NOT DEFINED} 
-bash: key: NOT DEFINED
root@ubuntu10112:/opt/shelltest# key=1
root@ubuntu10112:/opt/shelltest# echo ${key:?NOT DEFINED}
1
root@ubuntu10112:/opt/shelltest# echo ${key?NOT DEFINED} 
1
root@ubuntu10112:/opt/shelltest# x=${varl:+work}
root@ubuntu10112:/opt/shelltest# echo $x

root@ubuntu10112:/opt/shelltest# 
root@ubuntu10112:/opt/shelltest# varl=454
root@ubuntu10112:/opt/shelltest# echo $x        

root@ubuntu10112:/opt/shelltest# x=${varl:+work}
root@ubuntu10112:/opt/shelltest# echo $x        
work

实际生产使用案例:
删除七天前的过期数据备份

find ${PATH-/tmp} -name "*.tar.gz" -type f -mtime +7| xargs rm -f  #当PATH未定义,则删除tmp目录下的文件,则不会导致异常和意外

案例二:
nginx启动脚本:

#!/bin/sh

### BEGIN INIT INFO
# Provides:       nginx
# Required-Start:    $local_fs $remote_fs $network $syslog $named
# Required-Stop:     $local_fs $remote_fs $network $syslog $named
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/nginx
NAME=nginx
DESC=nginx

# Include nginx defaults if available
if [ -r /etc/default/nginx ]; then
        . /etc/default/nginx
fi

STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/5/KILL/5}"

test -x $DAEMON || exit 0

. /lib/init/vars.sh
. /lib/lsb/init-functions
........

四、echo输出样式

具体参考 man console_codes
样例:

RED="\E[1;31m"
GREEN="\E[1;32m"
YELLOW="\E[1;33m"
BLUE="\E[1;34m"
PURPLE="\E[1;35m"
RES="\E[0m"
case "$1" in
        start|START)
                echo -e "$GREEN runing.....start! $RES"
                ;;
        stop|STOP)
                echo -e "$RED stoping.....please wait!$RES"
                ;;
        reload|RELOAD)
                echo -e "$BLUE reloading.......!$RES"
                ;;
        restart|RESTART)
                echo -e "$YELLOW restarting......! $RES"
                ;;
        *)
                echo -e "$PURPLE please input {start|stop|reload|restart}! $RES"

        esac

echo -e 可以识别转义字符,识别特殊字符并输出。
\E 可以用\033替代