shell脚本1部分
shell脚本就是将多条命令聚集在一个文件中,自上而下的执行文件的命令。
1、如何抒写一个脚本
shell 脚本的命名规范,能够快速定位到需要执行的脚本。
shell脚本中填写"脚本信息",方便后续修改,联系等。
//以上分别对应中文
shell 脚本中对难理解命令进行注释,方便后续使用一看便懂。
下面是一个完美脚本的内容:
#!/bin/bash
read -p "输入需要创建的文件名:" file
touch $file
if [ $? -ne 0 ];then
echo "文件创建错误"
else
echo "成功创建 $file 文件"
fi
2、运行脚本
第一种方式:脚本赋予执行权限运行,那上面的脚本举例:
[root@shell shells]
[root@shell shells]
输入需要创建的文件名:qin
成功创建 qin 文件
第二种方式:使用解释器运行脚本
[root@shell shells]
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
[root@shell shells]
输入需要创建的文件名:qin
成功创建 qin 文件
3、shell中的符号使用
~ //家目录 # cd ~ 代表进入当前用户家目录
! //执行历史命令 可配合history命令使用 “!!” 代表执行上一个命令
$ //引用变量
+ - * / % //加减乘除 配合 expr 使用
& //后台执行 配合nohap 和 jobs 一起使用
* // 是shell的通配符 匹配所有
; //在shell中一行执行连个命令 # ifdown ens33;ifup ens33
| //管道符 上个命令的输出作为下个命令的输入
\ //转义符
`` //反引号 命令中执行命令
’ ’ //单引号 脚本中的字符串需要使用单引号和双引号引用起来,单引号不能解释变量
" " //双引号 和单引号一样,双引号可以解释变量
演示以上难理解的几个符号使用:
[root@shell ~]
CentOS-Base.repo CentOS-Debuginfo.repo CentOS-Media.repo CentOS-Vault.repo
CentOS-CR.repo CentOS-fasttrack.repo CentOS-Sources.repo CentOS-x86_64-kernel.repo
[root@shell ~]
/root
[root@shell ~]
ls /etc/yum.repos.d/
CentOS-Base.repo CentOS-Debuginfo.repo CentOS-Media.repo CentOS-Vault.repo
CentOS-CR.repo CentOS-fasttrack.repo CentOS-Sources.repo CentOS-x86_64-kernel.repo
[root@shell ~]
/root
[root@shell ~]
pwd
/root
[root@shell ~]
171 pwd
172 ls /etc/yum.repos.d/
173 history
[root@shell ~]
pwd
/root
[root@shell ~]
2
[root@shell ~]
99
[root@shell ~]
expr: syntax error
[root@shell ~]
100
[root@shell ~]
2
[root@shell ~]
[1] 1866
[root@shell ~]
[root@shell ~]
[1]+ Running nohup yum install httpd -y &
[root@shell ~]
$USER
[root@shell ~]
root
4、重定向
//重定向符号
> 输出重定向到一个文件或设备 覆盖原来的文件 >! 输出重定向到一个文件或设备 强制覆盖原来的文件 >> 输出重定向到一个文件或设备 追加原来的文件 < 输入重定向到一个程序
//标准错误重定向符号
2> 将一个标准错误输出重定向到一个文件或设备 覆盖原来的文件 b-shell 2>> 将一个标准错误输出重定向到一个文件或设备 追加到原来的文件 2>&1 将一个标准错误输出重定向到标准输出 注释:1 可能就是代表 标准输出 >& 将一个标准错误输出重定向到一个文件或设备 覆盖原来的文件 c-shell |& 将一个标准错误 管道 输送 到另一个命令作为输入
//命令重导向示例
在 bash 命令执行的过程中,主要有三种输出入的状况,分别是:
标准输入;代码为 0 ;或称为 stdin ;使用的方式为 <
标准输出:代码为 1 ;或称为 stdout;使用的方式为 1>
错误输出:代码为 2 ;或称为 stderr;使用的方式为 2
演示:
[root@shell ~]
[root@shell ~]
[root@shell ~]
EOF的使用
<<EOF //开始
....内容
EOF //结束
演示:
[root@shell shells]
> test file
> hai mai ti 666
> EOF
[root@shell shells]
test file
hai mai ti 666
[root@shell shells]
> new file;
> EOF
[root@shell shells]
test file
hai mai ti 666
new file;
[root@shell shells]
fdisk /dev/sdb <<EOF
n
p
1
+3G
w
EOF
mkdir /data
mkfs.xfs /dev/sdb1 >> /dev/null
mount /dev/sdb1 /data >> /dev/null
df -hT | grep "sdb1"
shell脚本2部分
1、echo命令详解
-n: 不换行
-e: 若出现一下字符,则特别加以处理,而不会将他当成一般字符输出:
\a: 发出警告声
\d: 删除前一个字符
\c: 最后不加换行符
\t: tab 键
\n: 空格键
[root@shell ~]
date:
2021-08-25
[root@shell ~]
date:2021-08-25
[root@shell ~]
qinziteng
[root@shell ~]
[root@shell ~]
[root@shell ~]
AC
2、read命令详解
-p: 打印信息 print[打印]
-t: 限定时间 timeout[超时时间]
-s: 不显示输入的字符串
-n: 输入字符个数
[root@shell ~]
echo -n "Passwd:"
read -s pwd
echo "password is:$pwd"
[root@shell ~]
echo "请输入密码,3秒自动退出"
echo -n "Passwd:"
read -t 3 -s pwd
echo "请输入用户名,不得超过4个字符"
echo -n "Login:"
read -n 4
echo
echo "请输入密码,3秒自动退出"
echo -n "Passwd:"
read -t 3 -s pwd
echo
//-p选项能实现和echo命令一样的效果 我们改一下上面的代码 用一行表示出来
//需要注意 read -p 之后在使用其他参数需要在后面添加即可!
[root@shell ~]
echo "请输入你的账号 不得超过4个字符"
read -p "Login:" -n 4 login
echo
echo "请输入你的密码 不做操作3秒后自动退出"
read -p "Passwd:" -s -t 3 pwd
echo
echo "您的账号为$login 密码为: $pwd"
变量
1、变量分类
- 本地变量:用户私有变量,只有本地用户可以使用,保存在家目录的 .bash_profile 和 .bashrc文件中。
- 全局变量:所有用户都可以使用,保存在/etc/bashrc和/etc/profile文件中。
- 用户自定义变量:比如脚本中的变量
2、定义变量
定义变量
[root@shell ~]
在shell中变量名与值之间不得有空格!
读取变量内容
[root@shell ~]
haimati
取消变量
[root@shell ~]
[root@shell ~]
设置全局变量
全局变量需要在 /etc/bashrc 或者 /etc/profile 文件中定义;
如果没有在配置文件中定义,重启系统后会消失!!!
在添加变量时 前面添加export 即可,这样就是一个全局变量了,其他shell也能引用这个变量。
[root@shell ~]
export USER1='zhangsan'
[root@shell ~]
[root@shell ~]
zhangsan
[root@shell ~]
Last login: Tue Aug 31 20:52:16 CST 2021 on pts/1
[zhangsan@shell ~]$ echo $USER1
zhangsan
3、其他变量
readonly 只读变量
顾名思义,只读变量的值不可以被修改的。
[zhangsan@shell ~]$ readonly test=t1
[zhangsan@shell ~]$ echo $test
t1
[zhangsan@shell ~]$ test=test1
-bash: test: readonly variable
[zhangsan@shell ~]$ unset t1
[zhangsan@shell ~]$ declare -r test2=t2
[zhangsan@shell ~]$ echo $test2
t2
declare -p
readonly -p
位置变量
shell中还有一些预先定义的特殊只读变量,它们的值只有在脚本运行时才能确定。
$0 // 代表脚本本身名字
$1----9 //第一个位置参数------第九个文章参数
$# //脚本参数的个数总和
$@ //脚本的所有参数
$* //脚本的所有参数
//脚本演示
[root@shell shells]
echo "这个脚本的名字是: $0"
echo "参数一共有: $#"
echo "参数的列表是: $@"
echo "参数的列表是: $*"
echo "第一个位置参数是: $1"
echo "第二个位置参数是: $2"
echo "第三个位置参数是: $3"
[root@shell shells]
这个脚本的名字是: test.sh
参数一共有: 3
参数的列表是: 1 2 3
参数的列表是: 1 2 3
第一个位置参数是: 1
第二个位置参数是: 2
第三个位置参数是: 3
//上面说到位置变量是1-9 那第10个位置变量该怎么表示呢?这种情况就要用到花括号了。
[root@shell shells]
echo "这个脚本的名字是: $0"
echo "参数一共有: $#"
echo "参数的列表是: $@"
echo "参数的列表是: $*"
echo "第一个位置参数是: $1"
echo "第二个位置参数是: $2"
echo "第三个位置参数是: $3"
echo "第十二个位置参数是: ${12}"
[root@shell shells]
这个脚本的名字是: test.sh
参数一共有: 13
参数的列表是: 1 2 3 4 5 6 7 8 9 10 11 12 13
参数的列表是: 1 2 3 4 5 6 7 8 9 10 11 12 13
第一个位置参数是: 1
第二个位置参数是: 2
第三个位置参数是: 3
第十二个位置参数是: 12
数组
变量和数组的区别:一个变量只能定义一个值、一个数组可以定义多个值
1、基本数组
数组可以让用户一次赋予多个值,需要读取数据时只需要使用索引调用即可。
数组语法
数组定义和读出
[root@shell ~]
[root@shell ~]
c //第一个从0开始,打印出第2个,那就是c咯
数组赋值
1)一次赋多值
[root@shell ~]
[root@shell ~]
2)一次性赋单个值
[root@shell ~]
[root@shell ~]
[root@shell ~]
666
[root@shell ~]
777
查看数组
declare -a
[root@shell ~]
[root@shell ~]
0 1 2 3 4 5 666 777
[root@shell ~]
0 1 2 3 4 5 7 8
[root@shell ~]
3 4 5 666 777
[root@shell ~]
3 4
2、关联数组
基本数组和关联数组的区别是:基本数组的索引是从0 1 2 3 开始的,而关联数组可以修改索引名字。关联数组需要使用declare -A声明。
1)一次赋单个值
[root@shell ~]
[root@shell ~]
[root@shell ~]
[root@shell ~]
zhangsan 19
2)一次赋多个值
[root@shell ~]
[root@shell ~]
beijing ok
shell中的运算
1、数学比较运算
-eq 等于
-ne 不等于
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
可以使用test命令测试 返回值0为真 非0为假
[root@shell ~]
0
[root@shell ~]
1
[root@shell ~]
0
2、字符串比较运算
== 等于
!= 不等于
-n 是否不为空
-z 是否为空
使用test命令测试
[root@shell ~]
root
[root@shell ~]
0
[root@shell ~]
0
[root@shell ~]
1
3、文件比较运算
-e 检查文件是否存在(目录、文件都可以,只有它存在)
-d 检查文件是否存在,且为目录
-f 检查文件是否存在,且为文件
-r 检查文件是否存在,并有r可读权限
-w 检查文件是否存在,并有w可写权限
-x 检查文件是否存在,并有w可写权限
-O 检查文件是否存在并,且被当前用户所拥有
-G 检查文件是否存在,并且被当前用户所组
file1 -nt file2 检查file1是否比file2新
file1 -ot file2 检查file1是否比file2旧
使用test命令测试
[root@shell ~]
0
[root@shell ~]
1
[root@shell ~]
0
[root@shell ~]
1
[root@shell ~]
0
4、逻辑运算
&& 逻辑与运算
|| 逻辑或运算
! 逻辑非运算
逻辑运算注意事项:
逻辑与、逻辑或 运算都需要两个条件,逻辑非运算只能一个条件
口诀: 逻辑与运算 真真为真 真假为假 假假为假
逻辑或运算 真真为真 真假为真 假假为假
逻辑非运算 非假为真 非真为假
5、双小圆括号用法
(())可以在里面进行数学自增减运算 ,(())里面可自动引用变量不需要使用$应用。
((a=1+6)) 将1+6的值赋予给a变量
((b=a-1)) a变量的值-1 赋值给b变量
((c=a+b)) c变量的值等于ab变量相加的值
a=((1+6))
b=((a-1))
c=((a+b))
((a=3+5,b=a+10))
((a>7 && b==c))
echo $((a+10))
if 判断语句
1、单步if语句
适用范围:只需要一步判断
if [ condition ]
then
commands
fi
该语句翻译成汉语大致意思如下:
假如 [ 条件为真 ]
那么
执行什么操作
结束
演示:
[root@shell shell_if]
eraffif [ ! -d /tmp/abc ];then
mkdir /tmp/abc
fi eraff
2、if-then-else双步语句
if [ condition ]
then
commands
else
commands
fi
翻译中文大致意思为:
如果 [ 条件为真 ]
那么
执行什么操作
否则
执行什么操作
结束
演示:
[root@shell shell_if]
if [ $USER == 'root' ];then
echo "管理员好!"
else
echo "guest你好!"
fi
3、if-then-elif-else 多步语句
if [ condition1 ]
then
commands
elif [ condition2 ]
commands
......
else
commands
fi
翻译大致为:
假如 [ 条件1为真 ]
那么
执行什么操作
假如 [ 条件2为真 ]
那么
执行什么操作
.....
否则
执行什么操作
结束
演示:
[root@shell shell_if]
if [ $1 -eq $2 ];then
echo "$1 = $2"
elif [ $1 -ge $2 ];then
echo "$1 > $2"
else
echo "$1 < $2"
fi
4、嵌套if
演示:
[root@shell shell_if]
if [ $1 -eq $2 ];then
echo "$1=$2"
else
if [ $1 -gt $2 ];then
echo "$1>$2"
else
echo "$1<$2"
fi
fi
5、if 小技巧
1)条件符号使用双圆括号,可以在条件中植入数学表达式
演示:
[root@shell shell_if]
if (( 100%3+1>10 ));then
echo "大于10"
else
echo "小于10"
fi
2)条件符号使用双中括号,可以在条件中使用通配符
演示:
[root@shell shell_if]
for i in zi cc zz tt qq
do
if [[ $i == z* ]];then
echo $i
fi
done
for循环语句
很多人将for循环叫做 “条件循环” 因为for是按条件循环的。
1、for语法
for var in value1 value2 ....
do
commands
done
演示: 倒计时
[root@shell shell_for]
for i in `seq 9 -1 1`
do
echo $i
sleep 1
done
2、 类C语言for语法
C语言格式for循环格式
返回值为真则循环继续,返回值为假则退出循环>
for ((变量;条件;自增减运算))
do
commands
done
演示: 倒计时
[root@shell shell_for]
for (( i=10;i>0;i-- ))
do
echo $i
sleep 1
done
for (( n=10;n>0;n-- ))
do
echo "$n"
done
//双变量使用’,'逗号隔开即可 如下:
[root@shell shell_for]
for (( n=10,m=0;n>0,m<10;n--,m++ ))
do
echo -e "\t$n\t\t$m"
done
3、无限循环
[root@shell shell_for]
for ((;;))
do
echo "无限循环"
done
循环控制语句
1、sleep N 脚本执行休眠时间
演示1:倒计时
[root@shell shell_for]
echo "10秒倒计时:"
echo
for (( i=10;i>0;i-- ))
do
echo $i
sleep 1
done
演示2:监控主机存活
[root@shell ~]
for ((;;))
do
ping -c2 $1 &>/dev/null
if [ $? -eq 0 ];then
echo -e "`date +%F-%H-%M-%S` is \033[032m up \033[0m"
else
echo -e "`date +%F-%H-%M-%S` is \033[031m down \033[0m"
fi
sleep 5
done
2、continue 跳过某次循环
看下面一段代码,输出1-9 但是使用continue 跳过输出5
[root@shell ~]
for i in {1..10}
do
if [ $i -eq 5 ];then
continue
fi
echo $i
sleep 0.3
done
3、break 跳出循环
演示:输入Q则跳出循环,否则无限循环
[root@shell ~]
for ((;;))
do
read -p "输入一个字母:" ch
if [ $ch == 'Q' ];then
break
else
echo "您输入的字母是:$ch"
fi
done
//如果循环多层嵌套,循环从里往外排序 0-N,如果想跳出某层循环 使用 break N
如下:
[root@shell ~]
for (( i=1;i<100;i++ ))
do
echo "外循环 $i"
for ((;;))
do
echo "内循环 $i"
break 2
done
done
while循环语句
while循环和for循环语法上都几乎一致,都是当条件true时进行循环,当条件为fake时终止循环。
很多小伙伴不知道什么时候使用for 什么时候使用while循环,根据场景而定吧,当明确知道要循环多少次的时候使用 for 循环,当不明确要循环多少次时,使用while循环。
1、while循环语法
while [ condition ]
do
commands
done
2、基本语法练习
演示:语法练习1
[root@shell while]
read -p "NUM:" num1
while [ $num1 -gt 0 ]
do
echo "大于"
sleep 1
done
演示:语法练习2
[root@shell while]
read -p "login:" account
while [ $account != 'root' ]
do
read -p "login:" account
done
演示:语法练习3
[root@shell while]
read -p "money:" money
read -p "car:" car
read -p "house" house
while [ $money -lt 100000 ] || [ $car -lt 1 ] || [ $house -lt 1 ]
do
echo "不同意"
read -p "money:" money
read -p "car:" car
read -p "house" house
done
echo "同意啦"
演示:语法练习4
[root@shell while]
read -p "请输入一个char:" char
while [ $char != 'Q' ]
do
read -p "请输入一个char:" char
done
3、嵌套 循环控制练习
演练:嵌套if语句
[root@shell while]
i=1
while [ $i -lt 10 ]
do
echo $i
if [ $i -eq 5 ];then
break
fi
i=$((i+1))
done
演练:嵌套if语句
[root@shell while]
i=0
while [ $i -lt 10 ]
do
i=$((i+1))
if [ $i -eq 5 ];then
continue
fi
echo $i
done
演练:嵌套for 打印99乘法表
[root@shell while]
n=1
while [ $n -lt 10 ];do
for ((m=1;m<=$n;m++));do
echo -n -e "$m * $n =$((n*m))\t"
done
echo
n=$((n+1))
done
演练:嵌套while 打印99乘法表
[root@shell while]
n=1
while [ $n -lt 10 ];do
m=1
while [ $m -le $n ];do
echo -n -e "$m * $n =$((m*n))\t"
m=$((m+1))
done
echo
n=$((n+1))
done
until语句
until和while正好相仿,until是条件为假开始循环,条件为真停止循环
until [ condition ]
do
commands
done
演示:打印10-20数字
[root@shell until]
int_num=10
until [ $int_num -gt 20 ];do
echo "$int_num"
int_num=$((int_num+1))
done
case多条件分支语句
case和if一样也是判断语句,和if相比case更适合做多条件判断。
case 判断语法
case 变量 in
条件1)
执行条件1代码块
;;
条件2)
执行条件2代码块
;;
........
*)
条件不是1和2 执行的代码块
;;
esac
注意:每个代码块执行完成后;;表示代码块执行结束 ,case结尾要以倒过来写esac,来结束。
演示:丈母娘家串门
[root@shell until]
read -p "丈母娘家串门,开门的是:" N
case $N in
伯母|丈母娘)
echo "伯母好"
echo "伯母辛苦了"
;;
伯父|老丈人)
echo "伯父好"
echo "伯父真帅"
;;
奶奶|老奶奶)
echo "奶奶好"
echo "奶奶 奶奶吉祥"
;;
*)
echo "脚本$0 可选值为 伯母|伯父|奶奶"
esac
函数
函数听起来很高大上,其实so easy,就是将脚本中的代码模块化,起个函数名字,之后可以多个调用这个函数。
由于函数是将代码模块化,出现问题了也容易排查。
函数语法
function 函数名字 {
代码块
}
函数名字(){
代码块
}
|