1、变量声明
# 在声明变量的时候,不用加$, 并且等号的两边不能留有空格
a=1111
# 引用变量的时候需要用$进行修饰
echo $a
# 如果只需要引用变量,那么可以使用$变量名即可,如果需要对变量做处理,那么就需要使用${}, 其他方法可以参看另外一篇内容
echo ${a:1:1} # 表示从变量a中截取顺序为1的且位数为1位
# 通过关键字export 把变量变为全局变量
export a # 注意这里不需要使用 $修饰
# 查询全局是否有该变量
env | grep ^a # 注意这里使用的是 ^符号
# 删除变量使用关键字,并且前面也不使用$修饰
unset a
变量声明的方法
# 声明数字, 使用关键字 declare
declare -i a=1
declare -i b=2
declare -i c=$a+$b
# 声明只读的变量
declare -r a="test" # 这个时候即不可以用unset删除,也不能重新赋值,但是退出终端即消失
# 声明全局变量
declare -x even="even" # 相当于export出去
# 声明索引数组 -a
# 声明关联数组 -A
普通数组的定义方式
# 方式一
arr[0]=1
arr[1]=2
# 方式二, 注意该方式中是用空隔隔开的
arr=(1 2 3)
# 查询数组所有项
echo ${arr[*]}
# 查询数组的长度
echo ${#arr[*]}
# 查询数组里的索引下标
echo ${!arr[*]}
# 获取数组指定的项
echo ${arr[*]:1:1}
# 可以把命令结果赋值给数组
arr=($(ls ./))
# 查看所有的数组
declare -a
关联数组的定义
# 方式一
declare -A arr
arr[first]=aaa
arr[second]=bbb
# 方式二
declare -a array
array=([aaa]=AAA [bbb]=BBB)
# 其他的操作与普通数组一致
交互式变量定义
交互式变量定义的值 read 主要用于让用户去定义变量值
-p 提示信息
-n 字符数(限制变量的字符数)
-s 不显示
-t 超时(默认单位秒)(限制用户输入变量值的时间)
# 提示用户输入用户名
read -p "please input your name" name
echo $name # 可以输出用户输入的用户名
# 提示用户输入密码
read -s -p "please input your password" pass
echo $pass # 可以输出用户输入的密码
# 从文件中读取指定的字段
read name pass < test.txt # test.txt的内容是 aaa pass 注意分隔符是空隔
echo $name $pass #则可以输出指定的字段
# 一次指定多个字段
read name age #这时用户按次输入的值会被赋值给name与age, 达到一次赋值两个变量, 注意用空格隔开
2、变量的处理

1、${VAR:-DEFAULT},VAR没有定义或者为空则输出$DEFAULT的值(VAR不变)
echo ${test:-test} # 没有定义test的前提下,会使用 -后面的值,但是test的值还是空
2、${VAR:=DEFAULT},VAR没有定义或空则为$DEFAULT的值
echo ${test:=test} # 与上面不一样的是,test会被赋值为test
3、${#test} # 返回test这个变量值的长度
4、${test^^},把test中的所有小写字母转换为大写输出(不改变值)
5、${STR:POSITON},从$POSITON位置提取子串
6、${STR:POSITON:LENGTH},从$POSITON位置提取长度为$LENGTH子串
7、
${STR%SUBSTR},从$STR尾部查找匹配,删除最短匹配$SUBSTR的子串(正常顺序)
${STR%%SUBSTR},从$STR尾部查找匹配,删除最长匹配$SUBSTR的子串(正常顺序)
temp=/etc/nginx/conf.d/default.conf
echo ${temp%.*} # 输出 /etc/nginx/conf.d/default
echo ${temp%%.*} # 输出 /etc/nginx/conf
8、
${STR#SUBSTR},从$STR头查找匹配,删除最短匹配$SUBSTR的子串(非正常顺序)
${STR##SUBSTR},从$STR头部查找匹配,删除最长匹配$SUBSTR的子串(非正常顺序)
temp=/etc/nginx/conf.d/default.conf
echo ${temp#*.} # 输出 d/default.conf
echo ${temp##*.} # 输出 conf (可以利用该方法来获取extname)
3、简单的四则运算
默认情况下,shell就只能支持简单的==整数==运算
shell支持下面几种运算符
+ - * / %(取模,求余数)
Bash shell 的算术运算有四种方式:
1. 使用 $(( ))
2. 使用 $[ ]
3. 使用 expr 外部程式
4. 使用 let 命令(一般使用该语句进行再赋值操作)
(注意使用以下的运算符的时候,不需要使用$对值进行引用 如: a=1;b=2 echo $(( a+b )) )
注意: n=1 let n+=1 等价于let n=n+1
# 如果需要进行小数运算, 需要借助bc工具, 如果未安装,使用yum y install bc
[root@server shell01]# echo 1+1.5|bc
注意: i++ 与 ++i的区别在于前者是先赋值后计算,后者是先计算再赋值
a=1;b=1; let $c=a++ 与 let $d=++b 那么$c与$d的值是不一样的
4、条件判断
-
-
格式2: [ 条件表达式 ]
-
格式3: [[ 条件表达式 ]] 支持正则
-e 是否存在 不管是文件还是目录,只要存在,条件就成立
-f 是否为普通文件
-d 是否为目录
-S socket
-p pipe
-c character
-b block
-L 软link
三种语法格式:
test -e file 只要文件存在条件为真
[ -d /shell01/dir1 ] 判断目录是否存在,存在条件为真
[ ! -d /shell01/dir1 ] 判断目录是否存在,不存在条件为真
[[ -f /shell01/1.sh ]] 判断文件是否存在,并且是一个普通的文件
-s 判断文件是否有内容(大小),非空文件条件满足
说明:-s表示非空,! -s 表示空文件
说明:1.sh文件里有内容的。
[root@server shell01]# test -s 1.sh
[root@server shell01]# echo $?
0
[root@server shell01]# touch aaa
[root@server shell01]# cat aaa
[root@server shell01]# test -s aaa
[root@server shell01]# echo $?
1
[root@server shell01]# test ! -s aaa;echo $?
0
[root@server shell01]# test ! -s 1.sh
[root@server shell01]# echo $?
1
文件权限相关的判断
-r 当前用户对其是否可读
-w 当前用户对其是否可写
-x 当前用户对其是否可执行
-u 是否有suid
-g 是否sgid
-k 是否有t位
两个文件的比较判断
file1 -nt file2 比较file1是否比file2新
file1 -ot file2 比较file1是否比file2旧
file1 -ef file2 比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode
test file1 -nt file2
[ file1 -ot file2 ]
整数之间的判断
-eq 相等
-ne 不等
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
字符串之间的判断
-z 是否为空字符串 字符串长度为0,就成立
-n 是否为非空字符串 只要字符串非空,就是成立
string1 = string2 是否相等
string1 != string2 不等
[root@server shell01]# AAA=hello
[root@server shell01]# BBB=world
[root@server shell01]# test -z $AAA
[root@server shell01]# echo $?
1
[root@server shell01]# test -n $AAA
[root@server shell01]# echo $?
0
[root@server shell01]# [ $AAA = $BBB ]
[root@server shell01]# echo $?
1
[root@server shell01]# [ $AAA != $BBB ]
[root@server shell01]# echo $?
0
多重条件判断
逻辑判断符号:
-a 和 && (and 逻辑与) 两个条件同时满足,整个大条件为真
-o 和 || (or 逻辑或) 两个条件满足任意一个,整个大条件为真
[ 1 -eq 1 -a 1 -ne 0 ] 整个表达式为真
[ 1 -eq 1 ] && [ 1 -ne 0 ]
[ 1 -eq 1 -o 1 -ne 1 ] 整个表达式为真
[ 1 -eq 1 ] || [ 1 -ne 1 ]
[root@server shell01]# [ 1 -eq 0 ] && echo true || echo false
false
[root@server shell01]# [ 1 -eq 1 ] && echo true || echo false
true
&&:前面的表达式为真
||:前面的表达式为假
总结:
1、; && ||都可以用来分割命令或者表达式
2、; 完全不考虑前面的语句是否正确执行,都会执行;号后面的内容
3、&& 需要考虑&&前面的语句的正确性,前面语句正确执行才会执行&&后的内容;反之亦然
make && make install
4、|| 需要考虑||前面的语句的非正确性,前面语句执行错误才会执行||后的内容;反之亦然
5、如果&&和||一起出现,从左往右依次看,按照以上原则
数值比较示例
示例:
数值比较:
[root@server ~]# [ $(id -u) -eq 0 ] && echo "the user is admin" # $(id -u) 表示获取用户id
[root@server ~]$ [ $(id -u) -ne 0 ] && echo "the user is not admin"
[root@server ~]$ [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"
[root@server ~]# uid=`id -u`
[root@server ~]# test $uid -eq 0 && echo this is admin
this is admin
[root@server ~]# [ $(id -u) -ne 0 ] || echo this is admin
this is admin
[root@server ~]# [ $(id -u) -eq 0 ] && echo this is admin || echo this is not admin
this is admin
[root@server ~]# su - stu1
[stu1@server ~]$ [ $(id -u) -eq 0 ] && echo this is admin || echo this is not admin
this is not admin
[stu1@server ~]$
类C风格的数值比较:
注意:在(( ))中,=表示赋值;==表示判断
1159 ((1==2));echo $?
1160 ((1<2));echo $?
1161 ((2>=1));echo $?
1162 ((2!=1));echo $?
1163 ((`id -u`==0));echo $?
1209 ((a=123));echo $a
1210 unset a
1211 ((a==123));echo $?
字符串比较:
注意:双引号引起来,看作一个整体;= 和 == 在 [ 字符串 ] 比较中都表示判断
1196 a='hello world';b=world
1197 [ $a = $b ];echo $?
1198 [ "$a" = "$b" ];echo $?
1199 [ "$a" != "$b" ];echo $?
1200 [ "$a" !== "$b" ];echo $? 错误
1201 [ "$a" == "$b" ];echo $?
1202 test "$a" != "$b";echo $?
思考:[ ] 和 [[ ]] 有什么区别?
1213 a=
1214 test -z $a;echo $?
1215 a=hello
1216 test -z $a;echo $?
1217 test -n $a;echo $?
1217 test -n "$a";echo $?
# [ '' = $a ];echo $?
-bash: [: : unary operator expected
2
# [[ '' = $a ]];echo $?
0
1278 [ 1 -eq 0 -a 1 -ne 0 ];echo $?
1279 [ 1 -eq 0 && 1 -ne 0 ];echo $?
1280 [[ 1 -eq 0 && 1 -ne 0 ]];echo $?
注意:获取参数的个数是 $# 获取所有的参数 $* ,获取上一个语句的执行状态是 $? 0表示正常 非0表示不正常
5、流程控制语句
if语句
if [ command ];then
符合该条件执行的语句
elif [ command ];then
符合该条件执行的语句
else
符合该条件执行的语句
fi
常用参数
常用的:
[ -a FILE ] 如果 FILE 存在则为真。
[ -d FILE ] 如果 FILE 存在且是一个目录则返回为真。
[ -e FILE ] 如果 指定的文件或目录存在时返回为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则返回为真。
[ -r FILE ] 如果 FILE 存在且是可读的则返回为真。
[ -w FILE ] 如果 FILE 存在且是可写的则返回为真。(一个目录为了它的内容被访问必然是可执行的)
[ -x FILE ] 如果 FILE 存在且是可执行的则返回为真。
不常用的:
[ -b FILE ] 如果 FILE 存在且是一个块文件则返回为真。
[ -c FILE ] 如果 FILE 存在且是一个字符文件则返回为真。
[ -g FILE ] 如果 FILE 存在且设置了SGID则返回为真。
[ -h FILE ] 如果 FILE 存在且是一个符号符号链接文件则返回为真。(该选项在一些老系统上无效)
[ -k FILE ] 如果 FILE 存在且已经设置了冒险位则返回为真。
[ -p FILE ] 如果 FILE 存并且是命令管道时返回为真。
[ -s FILE ] 如果 FILE 存在且大小非0时为真则返回为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID位时返回为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则返回为真。
[ -G FILE ] 如果 FILE 存在且默认组为当前组则返回为真。(只检查系统默认组)
[ -L FILE ] 如果 FILE 存在且是一个符号连接则返回为真。
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则返回为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则返回为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 比 FILE2 新, 或者 FILE1 存在但是 FILE2 不存在则返回为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 老, 或者 FILE2 存在但是 FILE1 不存在则返回为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则返回为真。
例子1:判断对一个地址是否通ping通
#! /bin/bash
if [ $# -ne 1 ]
then echo "usage:$0 remote_ip" && exit;
fi
ping -c1 $1 &>/dev/null # &>/dev/null表示需要执行结果,但是执行不输出过程, 注意在执行的过程中$0表示执行的程序文件名,$1才是参数, $@表示获取所有的参数
[ $? -eq 0 ] && echo "ping通$1" || echo "ping不通$1";
例子2: 判断指定的进程是否存在
判断进程存在的方法有
- ps -ef | grep 应用 | grep -v grep
- pgrep 应用(可以匹配到部份,所以不推荐)
- pidof (推荐)
#! /bin/bash
read -p "请输入需要查询的应用名称:" content;
pidof $content &>/dev/null;
[ $? -eq 0 ] && echo "该进程 $content 存在" || echo "该进程 $content 不存在";
例子3:判断指定的地址是否可以正常访问
#!/bin/bash
wget http://10.1.1.2 &>/dev/null
[ $? -eq 0 ] && echo "该web服务是正常的" && rm -f /shell/shell01/index.* || echo "该web服务异常请检查"
for循环
for variable in {list}
do
command
command
…
done
或者
for variable in a b c
do
command
command
done
语法结构举例说明:
# 从1到10循环
for var in {1..10};do echo $var;done
# 从1到5循环
for var in 1 2 3 4 5;do echo $var;done
# 从1到10循环
for var in `seq 10`;do echo $var;done
for var in $(seq 10);do echo $var;done
# 从0到10且步长为2
for var in {0..10..2};do echo $var;done
# 从0到10且步长为2
for var in {2..10..2};do echo $var;done
# 从10到1
for var in {10..1};do echo $var;done
# 从10到1步长为2
for var in {10..1..-2};do echo $var;done
for var in `seq 10 -2 1`;do echo $var;done
计算1-100的奇数之和
#! /bin/bash
declare -i sum;
for var in $(seq 1 2 100);
do
#sum=$[ var + sum ];
let sum+=$var
done;
echo $sum;
延伸
true 真
: 真
false 假
循环控制:
循环体: ==do....done==之间的内容
-
continue:继续;表示==循环体==内下面的代码不执行,重新开始下一次循环
-
break:打断;马上停止执行本次循环,执行==循环体==后面的代码
-
exit:表示直接跳出程序

浙公网安备 33010602011771号