shell基础知识
1.1第一个sh
sh -x 1.sh
+ touch /tmp/1.txt
+ chmod 600 /tmp/2.txt
+ mv /tmp/1.txt /tmp/2.txt
1.2脚本执行
bash 1.sh
./1.sh
-bash: ./1.sh: Permission denied
chmod +x 1.sh //赋予权限
./1.sh
2常用命令
2.1查看脚本执行过程
bash -x 1.sh
+ touch /tmp/1.txt
+ chmod 600 /tmp/2.txt
+ mv /tmp/1.txt /tmp/2.txt
2.2 查看脚本是否有语法错误
bash -n 1.sh #-n
2.3.1 显示年、月、日
date +%Y-%m-%d #年(以四位数字格式打印年份)月日
2022-09-23
date +%y-%m-%d #年(以两位数字格式打印年份)月日
22-09-23
date +%F #年(以四位数字格式打印年份)月日
2022-09-23
2.3.2 显示小时、分钟、 秒
date +%H:%M:%S #小时分钟秒
11:08:49
date +%T #小时分钟秒
11:08:56
2.3.3 显示星期
date +%w #一周中的第几天
5
date +%W #一年中的第几周
38
2.3.4 时间戳
date +%s #从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数
1663902654
date +%s
1663902658
2.3.5 显示一个小时之前/之后
date -d "+1 hour" #一个小时后
2022年 09月 23日 星期五 12:12:43 CST
date -d "-1 hour" #一个小时前
2022年 09月 23日 星期五 10:12:58 CST
2.3.6 表示一天之前/之后
date -d "+1day" #一天后
2022年 09月 24日 星期六 11:13:17 CST
date -d "-1day" #一天后
2022年 09月 22日 星期四 11:13:23 CST
3 变量
3.1 引用命令的结果
a=`date +%w`
echo $a
5
a=$(date +%w)
echo $a
5
3.2 1.1 与用户交互
read -p "请输入一个数字:" n
请输入一个数字:10
echo $n
10
read -p "请输入一个数字:"
请输入一个数字:100
echo $REPLY
100
3.3 内置变量
[root@shell shell]# sh bian.sh
$1=
第二个参数是
第三个参数是
本脚本一共有0个参数
$0是bian.sh
[root@shell shell]# sh bian.sh a b
$1=a
第二个参数是b
第三个参数是
本脚本一共有2个参数
$0是bian.sh
3.4 数学运算
[root@shell shell]# cat sum.sh
a=114514
b=114514
sum=$[$a*$b] #还可以采用sum=$(($a+$b))这种写法
echo "$a*$b=$sum"
[root@shell shell]# sh sum.sh
114514*114514=13113456196
4 shell中的逻辑判断
4.1 不带有else
[root@shell shell]# cat if1.sh
#!/bin/bash
a=10
if [ $a -gt 4 ]
then
echo ok
fi
[root@shell shell]# sh -x if1.sh
+ a=10
+ '[' 10 -gt 4 ']'
+ echo ok
ok
[root@shell shell]# sh -n if1.sh
4.2 带有else
[root@shell shell]# cat if2.sh
#!/bin/bash
a=10
if [ $a -gt 4 ]
then
echo ok
else
echo "not ok"
fi
[root@shell shell]# sh -x if2.sh
+ a=10
+ '[' 10 -gt 4 ']'
+ echo ok
ok
4.3 带有elif
[root@shell shell]# cat if3.sh
#!/bin/bash
a=13
if [ $a -gt 14 ]
then
echo ok
elif [ $a -gt 8 ]
then
echo "very ok"
else
echo "not ok"
fi
[root@shell shell]# sh -x if3.sh
+ a=13
+ '[' 13 -gt 14 ']'
+ '[' 13 -gt 8 ']'
+ echo 'very ok'
very ok
4.4 嵌套
[root@shell shell]# cat if4.sh
#!/bin/bash
a=10
if [ $a -gt 4 ]
then
if [ $a -lt 9 ]
then
echo "ok"
else
echo "very ok"
fi
else
echo "not ok"
fi
[root@shell shell]# sh -x if4.sh
+ a=10
+ '[' 10 -gt 4 ']'
+ '[' 10 -lt 9 ']'
+ echo 'very ok'
very ok
4.5 多个条件
if [ $a -gt 5 ] && [ $a -lt 10 ] == if [ $a -gt 5 -a $a -lt 10] # -a表示 and
if [ $b -gt 5 ] || [ $b -lt 3] == if [ $b -gt 5 -o $b -lt 3 ] # -o表示 or
4.6 if逻辑判断
4.6.1 if判断文件的目录属性
-e:判断文件或目录是否存在。
-d:判断是不是目录以及是否存在。
-f:判断是不是普通文件以及是否存在。
-r:判断是否有读权限。
-w:判断是否有写权限。
-X:判断是否可执行。
[root@shell shell]# ls -al
总用量 72
drwxr-xr-x. 2 root root 277 9月 23 11:18 .
dr-xr-x---. 4 root root 176 9月 23 09:14 ..
-rwxr-xr-x. 1 root root 75 9月 22 11:13 1.sh
-rwxrwxrwx. 1 root root 135 9月 22 14:38 bian.sh
-rw-r--r--. 1 root root 121 9月 23 09:11 break1.sh
-rw-r--r--. 1 root root 636 9月 23 08:48 case.sh
-rw-r--r--. 1 root root 185 9月 23 09:12 continue1.sh
-rw-r--r--. 1 root root 118 9月 23 09:14 exit1.sh
-rw-r--r--. 1 root root 87 9月 23 08:50 for.sh
-rw-r--r--. 1 root root 118 9月 23 09:17 fun1.sh
-rw-r--r--. 1 root root 49 9月 23 09:19 fun2.sh
-rw-r--r--. 1 root root 154 9月 23 09:20 fun3.sh
-rw-r--r--. 1 root root 50 9月 22 15:09 if1.sh
-rw-r--r--. 1 root root 69 9月 22 15:13 if2.sh
-rw-r--r--. 1 root root 108 9月 22 15:15 if3.sh
-rw-r--r--. 1 root root 115 9月 22 15:19 if4.sh
-rw-r--r--. 1 root root 101 9月 22 14:53 sum.sh
-rw-r--r--. 1 root root 389 9月 23 09:53 web.sh
-rw-r--r--. 1 root root 288 9月 23 09:03 while2.sh
-rw-r--r--. 1 root root 247 9月 23 08:54 while.sh
[root@shell shell]# if [ -f 1.sh ]; then echo ok; fi
ok
[root@shell shell]# if [ -e 1.sh ]; then echo ok; fi
ok
[root@shell shell]# if [ -d 1.sh ]; then echo ok; fi
[root@shell shell]# if [ -r 1.sh ]; then echo ok; fi
ok
[root@shell shell]# if [ -w 1.sh ]; then echo ok; fi
ok
[root@shell shell]# if [ -x 1.sh ]; then echo ok; fi
ok
4.6.2 if判断的一些特殊用法
[root@shell shell]# a=1
[root@shell shell]# if [ -z "$a" ];then echo "a为空"; fi [root@shell shell]# if [ ! -z "$a" ];then echo "a为空"; fi
a为空
[root@shell shell]# a=
[root@shell shell]# if [ ! -z "$a" ];then echo "a为空"; fi
[root@shell shell]# if [ -z "$a" ];then echo "a为空"; fi
a为空
if grep -q '123' 1.sh; then echo "1"; fi
[root@shell shell]#
[root@shell shell]#
[root@shell shell]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@shell shell]# grep -q root /etc/passwd
[root@shell shell]# echo $?
0
[root@shell shell]# grep -q root123 /etc/passwd
[root@shell shell]# echo $?
1
[root@shell shell]# a=1
[root@shell shell]# if(($a<1)); then echo 1; fi
[root@shell shell]# if(($a>1)); then echo 1; fi
[root@shell shell]# if(($a==1)); then echo 1; fi
1
[root@shell shell]# if(($a!=1)); then echo 1; fi
[root@shell shell]# a=2
[root@shell shell]# if(($a<1)); then echo 1; fi
[root@shell shell]# if(($a>1)); then echo 1; fi
1
[root@shell shell]# if(($a==1)); then echo 1; fi
[root@shell shell]#
[root@shell shell]# if(($a!=1)); then echo 1; fi
1
[root@shell shell]#
[root@shell shell]# a=
[root@shell shell]# if(($a!=1)); then echo 1; fi
-bash: ((: !=1: 语法错误: 期待操作数 (错误符号是 "!=1")
4.7 shell中的case判断
[root@shell shell]# cat case.sh
#!/bin/bash
read -p "Please input a number:" n
if [ -z "$n" ]
then
echo "Please input a number."
exit 1
fi
n1=`echo $n|sed 's/[0-9]//g'` 确定变量n是否为纯数字,如果是数字,则清空,不是,赋值给变量n1
if [ -n "$n1" ] #不为n1不为空
then
echo "Please input a number."
exit 1
fi
if [ $n -lt 60 ] && [ $n -ge 0 ]
then
tag=1
elif [ $n -ge 60 ] && [ $n -lt 80 ]
then
tag=2
elif [ $n -ge 80 ] && [ $n -lt 90 ]
then
tag=3
elif [ $n -ge 90 ] && [ $n -le 100 ]
then
tag=4
else
tag=0
fi
case $tag in
1)
echo "not ok"
;;
2)
echo "ok"
;;
3)
echo "very ok"
;;
4)
echo "oook"
;;
*)
echo "The number range is 0-100."
;;
esac
[root@shell shell]# sh case.sh
Please input a number:1
not ok
[root@shell shell]# sh case.sh
Please input a number:81
very ok
[root@shell shell]# sh case.sh
Please input a number:66
ok
[root@shell shell]# sh case.sh
Please input a number:100
oook
5 shell中的循环
5.1 for循环
vi for1.sh
#!/bin/bash
sum=0
for i in `seq 1 10`
do
sum=$[$sum+$i]
echo $i
done
echo $sum
sh for.sh
1
2
3
4
5
6
7
8
9
10
55
5.2 while循环
vi while1.sh
#!/bin/bash
while : #此处冒号表示死循环
do
load=`w|head -1|awk -F 'load average:' '{print $2}'|cut -d. -f1` #赋值给变量load #会将系统的负载,负载到load的变量里。
if [ $load -gt 10 ]
then
top|mail-s "load is high: $load" asldkfls011.com #将load大于10的信息发送邮箱给asldkfls011.com
fi
sleep 30 #休眠30秒,30s之后循环执行
done
[root@shell shell]# sh -x while.sh
+ :
++ w
++ head -1
++ cut -d. -f1
++ awk -F 'load average:' '{print $2}'
+ load=' 0'
+ '[' 0 -gt 10 ']'
+ sleep 30
+ :
++ w
++ head -1
++ awk -F 'load average:' '{print $2}'
++ cut -d. -f1
+ load=' 0'
+ '[' 0 -gt 10 ']'
+ sleep 30
6 shell中的中断与继续
6.1 跳出循环
vi break1.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
break #终止, 跳出该层循环
fi
echo $i
done
echo aaaaa
sh break1.sh
1
1
2
2
3
aaaaa
6.2 结束本次循环
vi continue1.sh #创建一个shell脚本
#!/bin/bash
for i in `seq 1 5 `
do
echo $i
if [ $i == 3 ]
then
continue #此处continue表示若 $i == 3 则结束本次循环
fi
echo $i
done
echo $i
sh continue1.sh
1
1
2
2
3
4
4
5
5
5
6.3 退出整个脚本
vi exit1.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i == 3 ]
then
exit
fi
echo $i
done
echo aaaa
[root@shell shell]# sh -x exit1.sh
++ seq 1 5
+ for i in '`seq 1 5`'
+ echo 1
1
+ '[' 1 == 3 ']'
+ echo 1
1
+ for i in '`seq 1 5`'
+ echo 2
2
+ '[' 2 == 3 ']'
+ echo 2
2
+ for i in '`seq 1 5`'
+ echo 3
3
+ '[' 3 == 3 ']'
+ exit
7 shell中的函数
7.1 打印出第一个、第二个参数、参数的个数及脚本名
vi fun1.sh
#/bin/bash
input()
{
echo $1 $2 $# $0 # 函数的参数:$1 $2 $# ;$0则是脚本的名字
# $#是
}
input 1 a b
[root@shell shell]# sh -x fun1.sh
+ input 1 a b c
+ echo 1 a 4 fun1.sh
1 a 4 fun1.sh
7.2 加法的函数
[root@shell shell]# vi fun2.sh
#!/bin/bash
sum()
{
s=$[$1+$2]
echo $s
}
sum 1 2
[root@shell shell]# sh -x fun2.sh
+ sum 1 2
+ s=3
+ echo 3
3
7.3 获得一个网卡的IP地址
[root@shell shell]# vi fun3.sh
#!/bin/bash
ip()
{
ifconfig |grep -A1 "$1: " |tail -1 |awk '{print $2}'
}
read -p "Please input the eth name: " e
myip=`ip $e`
echo "$e address is $myip"
[root@shell shell]# sh -x fun3.sh
+ read -p 'Please input the eth name: ' e
Please input the eth name: ens33
++ ip ens33
++ ifconfig
++ tail -1
++ grep -A1 'ens33: '
++ awk '{print $2}'
+ myip=192.168.200.149
+ echo 'ens33 address is 192.168.200.149'
ens33 address is 192.168.200.149
8 shell中的数组
8.1 数组读取
[root@shell shell]# a=(1 2 3 4 5)
[root@shell shell]# echo ${#a[@]}
5
[root@shell shell]# echo ${a[@]}
1 2 3 4 5
[root@shell shell]# echo ${a[0]}
1
[root@shell shell]# echo ${a[5]}
[root@shell shell]# echo ${a[4]}
5
[root@shell shell]# echo ${a[3]}
4
8.2 数组赋值
[root@shell shell]# echo ${a[*]}
1 2 3 4 5
[root@shell shell]# a[1]=100
[root@shell shell]# echo ${a[*]}
1 100 3 4 5
[root@shell shell]# a[5]=2
[root@shell shell]# echo ${a[@]}
1 100 3 4 5 2
[root@shell shell]# echo ${a[*]}
1 100 3 4 5 2
a[7]=114514
[root@shell shell]# echo ${a[*]}
1 100 3 4 5 2 114514
[root@shell shell]# echo ${a[7]}
114514
[root@shell shell]# echo ${a[6]}
8.3 数组的删除
unset a[7]
echo ${a[*]}
1 100 3 4 5 2
[root@shell shell]# unset a
[root@shell shell]# echo ${a[*]}
[root@shell shell]#
8.4 数组分片
[root@shell shell]# a=(`seq 1 5`)
[root@shell shell]# echo ${a[*]}
1 2 3 4 5
[root@shell shell]# echo ${a[*]:0:3}
1 2 3
[root@shell shell]# echo ${a[*]:1:4}
2 3 4 5
[root@shell shell]# echo ${a[*]:0-3:2}
3 4
[root@shell shell]# echo ${a[*]:0-2:2}
4 5
8.5 数组替换
[root@shell shell]# a=(a b c d e)
[root@shell shell]# echo ${a[*]}
a b c d e
[root@shell shell]# echo ${a[@]/b/100}
a 100 c d e
[root@shell shell]# echo ${a[*]}
a b c d e
[root@shell shell]# a=(a b c d e)
[root@shell shell]# echo ${a[*]}
a b c d e
[root@shell shell]# a=(${a[@]/100/b})
[root@shell shell]# echo ${a[@]/b/100}
a 100 c d e