Shell变量核心基础知识与实践
1.shell变量知识
1.什么是变量?
就是用一个字符或字符串,表示一堆的内容,这个字符或字符串就叫变量,如x=1,x就是变量,=赋值,=表示相等,等号右边的内容,变量的内容。
2.Shell变量特性
默认情况下,在bash Shell中是不会区分变量是什么类型 的,例如:常见的变量类型为整数、字符串、小数等。
3.Shell变量分类
变量可分为两类:环境变量(全局变量)和普通变量 (局部变量)。环境变量也可称为全局变量,可以在创 建他们的Shell及其派生出来的任意子进程Shell中使用, 环境变量又可分为自定义环境变量和bash内置的环境变 量。普通变量也可称为局部变量,只能在创建他们的 Shell函数或Shell脚本中使用。普通变量一般由开发者在开发脚本程序时创建。
1.2 shell环境变量(全局变量)介绍
环境变量一般是用export内置命令导出的变量,用于定义Shell的运行环境,保证Shell命令的正确执行。Shell通过环境变量来确定登录用户名、命令路径、 终端类型、登录目录等,所有的环境变量都是系统全局变量,可用于所有子进程中,这包括编辑器、Shell脚本和各类应用。
1.2.1 操作shell环境变量
1.显示环境变量
echo $变量名字
env,set
2.定义环境变量,3种方法:变量名尽量大写
1)export A=1
2)B=1
export B
3)declare
declare -x A=1
3.取消环境变量
unset 变量名
1.2.2 环境变量初始化与对应文件生效顺序
1.环境变量的文件:
全局文件
/etc/profile
/etc/bashrc
用户环境变量文件
~/.bashrc
~/.bash_profile
2.环境变量初始化与对应文件生效顺序:优先加载/etc/profile,然后加载~/.bash_profile再次加载~/.bashrc,最后加载/etc/bashrc
~/.bash_profile 4
~/.bashrc 3
/etc/bashrc 2
/etc/profile 1
1.3 普通变量(局部变量)
当前用户或者脚本中生效,离开当前用户或者脚本就会失效
1.3.1 操作shell普通变量
1.定义普通变量
规则:见名知意,字母、数字、下划线,3者组合,以字母开头
1)OldboyAge=1
2)oldboy_age=1
3) oldboyAge=1 ###驼峰语法
2.变量内容
字符串:
变量名=value #<==不加引号。 ##解析变量或者命令,然后输出,纯数字选择不加引号。
变量名=’value’ #<==加单引号。 ###所见即所得
变量名=”value” #<==加双引号。 ##解析变量或者命令,然后输出,字符串默认选择双引号,可以把要定义的内容作为一个整体。
3.命令变量
变量名=`ls`
变量名=$(ls)
1.3.2 普通变量定义及输出小结
针对变量名:
1)变量名的定义要有一定的命令规范,并且要见名知意,OldboyAge=1,推荐使用驼峰语法。
2)变量名仅能使用字母、数字、下划线中的任意多个字符,并且要字母开头。
针对变量内容:
3)在脚本中定义普通字符串变量,尽量把变量的内容用双引号括起来。
4)单纯数字的变量内容可以不加引号。
5)希望变量的内容原样输出需加单引号。
6)希望变量值引用命令并获取命令的结果就用反引号或$()。
针对赋值符号:
7)变量定义使用赋值符号(=),赋值符号两端不要有空格。
针对变量输出:
8)使用或者输出变量的内容,可用$变量名,例如:echo $OldboyAge。
9)若变量名(db)后面有其他字符连接的时候,就必须给变量名加上大括号{},例如:$db_t就要改成${db}_t
1.4 Shell特殊重要变量
1.4.1 shell特殊位置变量
在Shell中存在一些特殊且重要的变量,例如:、0、1、$#,我们称之为特殊位置参数变量,要从命令行、函数、或脚本执行等处传递参数时,就需要在 Shell脚本中使用位置参数变量
位置变量 | 作用说明 | 企业应用 |
$0 |
获取当前脚本的名称,如脚本前面跟着路径的话,那就获取脚本的路径加名称 |
一般在启动脚本的结尾会使用$0获取脚本的路径和名字给用户提示用 |
$n |
获取当前脚本的第n个参数值,n=1..9,当n为0时表示文件名,如果n大于9,则需要用大括号括起来,例如${10},接的参数以空格分隔 |
一般用于选择脚本的启动,停止等 |
$* |
获取当前脚本所有传参的参数,不加引号作用同$@,如果给$加上引号,例如:"$",则表示将所有的参数视为单个字符,例如"$1 $2 $3" |
当需要接收脚本后面所有参数时,但是又不知道参数个数就用这个变量 |
$@ |
获取当前脚本所有传参的参数,不加引号作用同$*,如果给$@加上引号,例如:"$@",则表示将所有的参数视为不同的独立字符串,例如"$1" "$2" "$3" |
当需要接收脚本后面所有参数时,但是又不知道参数个数就用这个变 |
1.4.2 shell进程特殊状态变量
状态变量 | 作用说明 |
$? |
获取上一个指令的执行状态返回值(成功为0,不成功非0) |
$$ |
获取当前脚本的进程号(PID) |
$! |
获取上一个在后台工作进程的进程号 |
$_ |
获取上一个命令或脚本的最后一个参数 |
1.4.3 shell变量子串知识
ID | 表达式 | 作用说明 |
1 |
${parameter} |
返回${parameter}变量内容 |
2 |
${#parameter} |
返回${parameter}内容长度(按字符) |
3 |
${parameter:offset} |
在变量${parameter}中,从位置offset之后提取子符串到结尾 |
4 |
${parameter:offset:length} |
在变量${parameter} 中,从位置offset之后提取长度为length的字符串 |
5 |
${parameter#word} |
从变量${parameter}开头删除最短匹配的word字符串 |
6 |
${parameter##word} |
从变量${parameter}开头删除最长匹配的word字符串 |
7 |
${parameter%word} |
从变量${parameter}结尾开始删除最短匹配的word字符串 |
8 |
${parameter%%word} |
从变量${parameter}结尾开始删除最长匹配的word字符 |
9 |
${parameter/pattern/string} |
使用string替换第一个匹配pattern |
10 |
${parameter//pattern/string} |
使用string替换所有匹配pattern |
1.4.4 shell特殊变量扩展
表达式 | 作用说明 | 用途 |
${parameter:-word} |
如果parameter变量为空或未赋值,就会返回字符串替代变量的值 |
如果变量未定义,则返回备用的值,防止变量为空或者未定义而导致异常 |
${parameter:=word} |
如果parameter变量为空或未赋值,就设置这个变量值为word并返回其值。位置变量与特殊变量不适用 |
基本同上一个${parameter:-word}相同,不同的是会额外给parameter变量赋值 |
${parameter:?word} |
如果parameter变量为空或未赋值,word字符串将被作为标准错误输出,否则输出变量的值 |
用于捕捉由于变量未定义而导致的错误,并退出程序 |
${parameter:+word} |
如果parameter变量为空或未赋值,则什么不做,否则word字符串会替代变量的值 |
|
2. shell变量的数值计算
2.1 算术运算符
2.2 bash编程常见运算命令汇总
运算操作符与运算命令 | 意义 |
(()) |
用于整数运算的常用运算符 |
let |
用于整数运算,类似(()) |
expr |
用于整数运算,但还有其它的额外功能 |
s[] |
用于整数运算 |
bc |
用于小数或整数运算 |
awk |
用于小数或整数运算 |
declare |
定义变量值和属性,-i参数可以用于定义整形变量,做运算 |
2.3 双小括号“(())”数值运算的基础语法
运算操作符与运算命令 | 意义 |
((i=i+1)) |
此种书写方法,先运算后赋值法,即将i+1的结果赋值给变量i,不能使用echo"((i=i+1))"的输出形式,可以使用echo $((i=i+1))输出其值 |
i=可以在前加((i+1))|可以在(())前加符,将表达式运算后赋值给i |
|
((8>7&&5==5)) |
可以进行比较操作,还可以加入逻辑或与逻辑与,用于条件判断 |
echo 需要直接输出运算表达式结果可以在前加((2+1))|需要直接输出运算表达式结果可以在(())前加 |
|
2.4 let运算语法
语法格式: let 赋值表达式
let赋值表达式同等于((赋值表达式))
[root@ci-node1 scripts]# aa=12
[root@ci-node1 scripts]# let i=$aa+10
[root@ci-node1 scripts]# echo $i
22
[root@ci-node1 scripts]#
2.5 expr命令计算基本用法
[root@ci-node1 scripts]# expr 2 + 2
4
[root@ci-node1 scripts]# expr 2 \* 2
4
[root@ci-node1 scripts]# expr 2 / 2
1
注意:使用expr时,运算符与计算的数所必须要有空格隔开,使用*号时需要使用转义符\进行转义
2.5.1 expr其它用法,判断一个数字是否为整数
[root@ci-node1 scripts]# i=5
[root@ci-node1 scripts]# expr $i + 6 &>/dev/null #&>/dev/null表示不保留任务的输出
[root@ci-node1 scripts]# echo $?
0
[root@ci-node1 scripts]# expr $i + 6a &>/dev/null
[root@ci-node1 scripts]# echo $?
2
使用expr判断数字是否为整数,如果echo $?返回0则表示是一个整数,返回非0则表示不是一个整数
#!/bin/bash
expr 2 + $1 & >/dev/null
if [ $? -ne 0 ]
then
echo "这不是一个整数"
else
echo "这是一个整数"
fi
2.5.2 使用expr判断文件扩展名是否符合要求
#!/bin/bash
expr "$1" : ".*\.txt" &>/dev/null
if [ $? -eq 0 ]
then
echo "$1 是文本"
else
echo "$1 不是文本"
fi
2.5.3 使用expr来计算字符串长度
[root@ci-node1 scripts]# oldboy="I am oldboy"
[root@ci-node1 scripts]# expr length "$oldboy"
11
2.6 适合小数运算的bc命令(需先安装bc命令)
[root@ci-node1 scripts]# echo 1.2+3.3|bc
4.5
[root@ci-node1 scripts]# echo 1.2*3.3|bc
3.9
[root@ci-node1 scripts]# echo 1.2/3.3|bc
0
[root@ci-node1 scripts]# echo 1.2%3.3|bc
1.2
[root@ci-node1 scripts]# echo "scale=2;335/113"|bc # scale表示保留几位小数
2.96
2.7 适合小数运算的awk命令
[root@ci-node1 scripts]# echo "335 113"|awk '{print ($1-$2)}' # $1表示第一个数字,$2表示第二个数字
222
[root@ci-node1 scripts]# echo "335 113"|awk '{print ($1*$2)}'
37855
[root@ci-node1 scripts]# echo "335 113"|awk '{print ($1+10)*$2}'
38985
3.特殊内置命令read
shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入中获取,read为bash内置命令,可以通过help read获取帮助
语法格式:read [参数] [变量名]
常用参数:
-p prompt:设置提示信息
-t tiemout:设置输入等待时间,单位默认为秒
3.1 基于shell变量输入read命令
将加减乘除计算的脚使用read方式读入整数变量
[root@ci-node1 scripts]# cat 4.sh
#!/bin/bash
read -p "请输入两个数字:" a b
echo "a-b=$(($a-$b))"
echo "a+b=$(($a+$b))"
echo "a*b=$(($a*$b))"
echo "a**b=$(($a**$b))"
echo "a/b=$(($a/$b))"
echo "a%b=$(($a%$b))"
[root@ci-node1 scripts]# sh 4.sh
请输入两个数字:11 22
a-b=-11
a+b=33
a*b=242
a**b=-2732210440490168087
a/b=0
a%b=11
4.shell脚本的条件测试与比较
4.1 条件表达式常见语法
条件测试语法 | 说明 |
test <测试表达式> |
利用test命令进行测试表达式的方法,test与测试表达式之间有一个空格 |
[测试表达式] |
这是通过中括号进行测试表达式的方法,与test用法相同,[]边界和内容之间至少 有一个空格 |
[[测试表达式]] |
这是通过双中括号进行测试表达式的方法 ,[[]]边界和内容之间至少 有一个空格 |
((测试表达式)) |
这是通过双小括号进行测试表达式的方法,一般用于if语句里,(())两端不需要空格 |
(命令表达式) |
这是通过小括号进行测试表达式的方法 |
`命令表达式` |
这是通过反引号进行测试表达式的方法 |
4.2 文件测试表达式的常见功能说明
常用文件测试参数 | 说明 |
-d(directory) |
文件存在且为目录则为真 |
-f文件,f全拼为file |
文件存在且为普通文件则为真 |
-e(exist) |
文件存在则为真,-e不辩别是目录还是文件 |
-r(read) |
文件存在且可读则为真 |
-s(size) |
文件存在且文件大小不为0则为真 |
-w(write) |
文件存在且文件可写则为真 |
-x(executable) |
文件存在且文件可执行则为真 |
-L(link) |
文件存在且为链接文件则为真 |
f1 -nt(newer than) f2 |
文件f1比文件f2新则为真,根据修改时间来算 |
f1 -ot(older than) f2 |
文件f1比文件f2旧则为真,根据修改时间来算 |
4.3 字符串测试表达式的常见功能说明
字符串参数 | 说明 |
-n "字符串" |
若字符串长度不为0则为真 |
-z "字符串" |
若字符串长度为0则为真 |
"字符串" = "字符串" |
若字符串相等则为真 |
"字符串" != "字符串" |
若字符串不相等则为真 |
4.4 整数测试表达式知识
[]与test中使用的比较符号 | (()) 与[[]]使用的符号 | 说明 |
-eq(equal) |
== |
等于 |
-ne(not equal) |
!= |
不等于 |
-gt(greater than) |
> |
大于 |
-lt(less than) |
< |
小于 |
-ge(greater equal) |
>= |
大于等于 |
-le(less equal) |
<= |
小于等于 |
ps:可以使用man test来查看更多的文件比较符号
4.5 逻辑测试表达式
4.6 条件表达式符号的语法对比