Shell是在Linux内核与用户之间的解释器程序,通常指的是bash,负责向内核翻译及传达用户/程序指令

执行一个未设置x权限的Shell脚本
以下三种方式任选其一:
bash 脚本文件路径
source 脚本文件路径
. 脚本文件路径
自定义Shell变量时,变量名规则
- 可以包括数字、字母、下划线,不能以数字开头
- 变量名区分大小写
- 赋值时等号两边不要有空格
- 尽量不要使用关键字和特殊字符
- 给同一个变量多次赋值时,最后一次的赋值生效
预定义变量$$、$?、$0、$#、$*、$!的作用。
$$ 保存当前运行进程的(PID)号
$? 保存命令执行结果的(返回状态)
$0 保存当前运行的(进程名)或(脚本名)
$# 保存位置变量的(个数)
$* 保存所有位置变量的(值)
$! 保存后台(最后一个进程)的PID号
三种定界符在变量赋值操作中的特点。
- 双引号 " ":允许扩展,以 $ 引用其他变量
- 单引号 ' ':禁用扩展,即便 $ 也视为普通字符
- 反撇号 ` `:将命令的执行输出作为变量值
[root@sv7 ~]# cat /etc/shells #查看所有解释器
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
[root@svr7 ~]# sh #切换成sh解释器
sh-4.2# ls #利用sh解释器输入命令
sh-4.2# exit #退出sh解释器
判断变量是否为空
-z 字符串的值为空
-n 字符串的值不为空(相当于! -z)[root@sv7 ~]# a=22
[root@sv7 ~]# [ -z "$a" ] #判断$a为空
[root@sv7 ~]# echo $? #结果错误,$a不为空,变量中有值
1
[root@sv7 ~]# [ -z "$b" ] #判断$b为空
[root@sv7 ~]# echo $? 结果错正确,$b为空,变量中无值
0
[root@sv7 ~]# [ ! -z "$a" ] #判断$a不为空,或者使用[ -n "$a" ]
[root@sv7 ~]# echo $? #结果正确,$a不为空,变量中有值
0
此时判断为不为空还没有什么意思,后面结合脚本使用才能看出更好的效果
一行执行多条命令的情况
# A ; B #执行A命令后执行B命令,两者没有逻辑关系
[root@sv7 ~]# ls;cd /tmp/ #查看结果,并切换到tmp目录
# A && B #仅当A命令执行成功,才执行B命令,&&并且的意思,执行失败则不往下执行[root@sv7 ~]# a=22
[root@sv7 ~]# [ ! -z "$a" ] && echo Y 判断$a不为空,命令执行成功,结果不为空,执行echo Y,显示结果为Y
Y
[root@sv7 ~]# [ -z "$a" ] && echo Y 判断$a为空,命令执行失败,实际结果变量值为空,不执行echo Y,结果不显示
# A || B #仅当A命令执行失败,才执行B命令,||或者的意思,A执行成功则不执行B,A执行失败,则执行B[root@sv7 ~]# [ -z "$a" ] && echo Y || echo N 判断$a为空,命令执行失败,实际结果变量值为空,不执行echo Y,执行echo N
N
判断字符串是否相等
[ 字符串1 操作符 字符串2 ]
== 两个字符串相同
[root@sv7 ~]# a=hello
[root@sv7 ~]# b=hello
[root@sv7 ~]# [ "$a" == "$b" ] && echo Y || echo N
Y
[root@sv7 ~]# b=world
[root@sv7 ~]# [ "$a" == "$b" ] && echo Y || echo N
N
!= 两个字符串不相同
[root@sv7 ~]# [ "$a" != "$b" ] && echo Y || echo N
Y
整数值比较:
参与比较的必须是整数(可以调用变量)
- -eq 等于(Equal)
- -ne 不等于(Not Equal)
- -ge 大于或等于(Greater or Equal)
- -le 小于或等于(Less or Equal)
- -gt 大于(Greater Than)
- -lt 小于(Less Than
1)-gt 大于
[root@sv7 ~]# [ 2 -gt 3 ] && echo Y || echo N
N
[root@sv7 ~]# [ 20 -gt 3 ] && echo Y || echo N
Y
2)-ge 大于或等于
[root@sv7 ~]# [ 5 -ge 3 ] && echo Y || echo N
Y
3)-lt 小于
[root@sv7 ~]# [ 20 -lt 3 ] && echo Y || echo N
N
4)-le 小于或等于
[root@sv7 ~]# [ 3 -le 3 ] && echo Y || echo N
Y
5)-eq 相等
[root@sv7 ~]# [ 3 -eq 3 ] && echo Y || echo N
Y
6)-ne 不相等
[root@sv7 ~]# [ 3 -ne 3 ] && echo Y || echo N
N
识别文件/目录的状态
1)-e 判断对象是否存在(不管是目录还是文件)
[root@sv7 ~]# [ -e "/etc" ] && echo Y || echo N
Y
[root@sv7 ~]# [ -e "/etc/hosts" ] && echo Y || echo N
Y
2)-d 判断对象是否为目录(存在且是目录)
[root@sv7 ~]# [ -d "/etc" ] && echo Y || echo N
Y
[root@sv7 ~]# [ -d "/etc/hosts" ] && echo Y || echo N
N
3)-f 判断对象是否为文件(存在且是文件)
[root@sv7 ~]# [ -f "/etc" ] && echo Y || echo N
N
[root@sv7 ~]# [ -f "/etc/hosts" ] && echo Y || echo N
Y
4)-r 判断对象是否可读
[root@sv7 ~]# [ -r "/etc/hosts" ] && echo Y || echo N
Y
5)-w 判断对象是否可写
[root@sv7 ~]# [ -w "/etc/hosts" ] && echo Y || echo N
Y
6)-x 判断对象是否具有x权限
[root@sv7 ~]# [ -x "/etc/hosts" ] && echo Y || echo N
N
[root@sv7 ~]# [ -x "/root/warn.sh" ] && echo Y || echo N
Y
if选择结构
1)if单分支的语法组成:
if 条件测试;then
命令序列
fi
判断用户的UID是等于0,如果是,显示:你是管理员,否则没反应(单分支)
1)编写脚本如下:
[root@sv7 ~]# vim a1.sh#!/bin/bash
if [ $UID -eq 0 ];then
echo "你是管理员"
fi
[root@sv7 ~]# chmod +x a1.sh
[root@sv7 ~]# ./a1.sh
你是管理员
2)if双分支的语法组成:
if 条件测试;then
命令序列1
else
命令序列2
fi
检测/root/dachui/目录,若存在则输出ok,若不存在则创建(双分支)
[root@sv7 ~]# vim dir.sh
#!/bin/bash
dir="/root/dachui"
if [ -d $dir ];then
echo ok
else
mkdir -p $dir
fi
[root@sv7 ~]# chmod +x dir.sh
[root@sv7 ~]# ./dir.sh
3)if多分支的语法组成:
if 条件测试1 ;then
命令序列1
elif 条件测试2 ;then
命令序列2
else
命令序列n
fi
从键盘读取一个数值,猜10(包括10)以内的数字大小(多分支示例)
[root@sv7 ~]# echo $RANDOM #使用RANDOM的变量(系统自带的变量),输出随机数
25246
[root@sv7 ~]# echo $[RANDOM%10] #使用产生的随机数除以10,求余数
2
[root@sv7 ~]# echo $[RANDOM%10]
1
[root@sv7 ~]# echo $[RANDOM%10+1] #(包括10)
8
1)脚本编写参考如下:
[root@sv7 ~]# vim run.sh
#!/bin/bash
num=$[RANDOM%10+1]
read -p "我有一个1-10的数字,你猜是啥:" cai
if [ $cai -eq $num ];then
echo "猜对了"(命令序列)
elif [ $cai -gt $num ];then
echo "猜大了"(命令序列)
else
echo "猜小了"(命令序列)
fi
[root@sv7 ~]# chmod +x run.sh
[root@sv7 ~]# ./run.sh
我有一个1-10的数字,你猜是啥:1
猜对了
for循环结构
使用for循环,语法结构如下所示:
for 变量名 in 值1 值2 值3 #值的数量决定循环任务的次数
do
命令序列
done
编写脚本,批量创建账户(for循环示例)
[root@sv7 ~]# vim name.txt #存放用户账号的文件
u1
u2
u3
u4
[root@sv7 ~]# vim adduser.sh
#!/bin/bash
for i in $(cat name.txt) #循环批量创建name.txt里面所有账户,文档中每行是一个用户名,该文档要提前创建,与脚本在同一目录下即可
do
useradd $i(命令序列)
done
[root@sv7 ~]# chmod +x adduser.sh
[root@sv7 ~]# ./adduser.sh
[root@sv7 ~]# id u1
uid=1004(u1) gid=1004(u1) groups=1004(u1)
批量检测多个主机的存活状态(for循环和if选择结合示例)
优化前面写好的ping脚本
1)编写脚本如下:,可以把{1..5}改为{1..254}测试整个网段
[root@sv7 ~]# vim ping.sh
#!/bin/bash
for i in {1..5}
do
ping -c 1 192.168.88.$i &> /dev/null(命令序列)
if [ $? -eq 0 ] ; then(命令序列)
echo "88.$i 网络正常"(命令序列)
else
echo "88.$i 网络异常"(命令序列)
fi
done
[root@sv7 ~]# ./ping.sh
88.1 网络异常
88.2 网络异常
88.3 网络异常
88.4 网络异常
88.5 网络异常
while循环结构
while循环属于条件式的执行流程,会反复判断指定的测试条件,只要条件成立即执行固定的一组操作,直到条件变化为不成立为止。所以while循环的条件一般通过变量来进行控制,在循环体内对变量值做相应改变,以便在适当的时候退出,避免陷入死循环。
使用while循环,语法结构如下所示:
while 条件测试 #根据条件的结果决定是否要执行任务,条件测试成功的话就执行,如果失败立刻结束循环
do
命令序列
done
[root@sv7 ~]# vim run.sh
#!/bin/bash
num=$[RANDOM%10+1]
while :
do
read -p "我有一个1-10的数字,你猜是啥:" cai
if [ $cai -eq $num ];then
echo "猜对了"
elif [ $cai -gt $num ];then
echo "猜大了"
else
echo "猜小了"
fi
done
150

被折叠的 条评论
为什么被折叠?



