Shell脚本结构与执行

1.shell脚本结构与执行

 

1.1 脚本结构

 

[root@localhost ~]# mkdir shell

 

[root@localhost ~]# cd shell

 

[root@localhost shell]# vi 1.sh   //写入如下内容

 

#!/bin/bash

 

touch /tmp/1.txt

 

chmod 600 /tmp/2.txt

 

mv /tmp/1.txt /tmp/2.txt

 

1.2 脚本执行

 

[root@localhost shell]# bash 1.sh

 

shell脚本还有一种执行方法,但前提是脚本本身要有执行权限,所以在执行前我们需要给脚本加一个x权限

 

[root@localhost shell]# chmod +x 1.sh   //赋予权限

 

[root@localhost shell]# ./1.sh      //执行脚本

 

2常用命令

 

2.1查看脚本执行过程

 

[root@localhost shell]# bash -x 1.sh

 

2.2 查看脚本是否有语法错误

 

[root@localhost shell]# bash -n 1.sh

 

2.3 date 命令

 

date +%Y-%m-%d  #年(以四位数字格式打印年份)月日

 

date +%y-%m-%d  #年(以两位数字格式打印年份)月日

 

date +%T     #小时分钟秒

 

date +%H:%M:%S  #小时分钟秒

 

date +%w     #一周中的第几天

 

date +%W     #一年中的第几周

 

使用命令date +%s 显示从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数。

 

使用命令 date -d @1647832130显示输入秒数之前的时间

 

 

 

date -d "+1 hour"  #一个小时后

 

date -d "-1 hour"  #一个小时前

 

date -d "+1day"   #一天后

 

date -d "-1 day"   #一天前

 

3.shell脚本中的变量

 

在shell脚本中使用变量可以节省时间并且使我们的脚本更加专业,所以当我们编写一个脚本时,就可以使用变量来代替某个使用频繁并且长度很长的字符串。变量的格式:“变量名=变量的值”。

 

3.1 引用命令的结果

 

当我们引用某个命令的结果时,可以使用变量代替

 

[root@localhost ~]# a= date +%w     #将命令结果赋值给变量

 

[root@localhost ~]# echo $a

 

[root@localhost ~]# a=$(date +%w)    #将命令结果赋值给变量

 

[root@localhost ~]# echo $a

 

3.2 与用户交互

 

[root@localhost ~]# read -p "请输入一个数字:" n
请输入一个数字:10
[root@localhost ~]# echo $n
10

 

[root@localhost ~]# read -p "请输入一个数字:"
请输入一个数字:100
[root@localhost ~]# echo $REPLY
100

 

3.3 内置变量

 

[root@localhost shell]# vi bian.sh     #创建一个名为bian.sh的脚本

 

[root@localhost shell]# cat bian.sh

 

#!/bin/bash

 

echo "$1=$1"

 

echo "第二个参数是$2"

 

echo "第三个参数是$3"

 

echo "本脚本一共有$#个参数"

 

echo "$0是$0"

 

[root@localhost shell]# sh bian.sh     #执行脚本

 

$1=

 

第二个参数是

 

第三个参数是

 

本脚本一共有0个参数

 

$0是bian.sh

 

[root@localhost shell]# sh bian.sh a b     #再次执行脚本

 

$1=a

 

第二个参数是b

 

第三个参数是

 

本脚本一共有2个参数

 

$0是bian.sh            # $0就是脚本的名字

 

3.4 数学运算

 

shell脚本中的变量常用于数学运算当中,示例如下:

 

[root@localhost shell]# vi sum.sh   #创建一个名为sum.sh的脚本

 

[root@localhost shell]# cat sum.sh

 

#!/bin/bash

 

a=1

 

b=2

 

sum=a+((b))这种写法

 

echo "b=$sum"

 

[root@localhost shell]# sh sum.sh    #执行脚本

 

1+2=3

 

4.shell中的逻辑判断

 

4.1 不带有else

 

基础结构:

 

if 判断语句; then

 

command

 

fi

 

示例如下:

 

[root@localhost shell]# vi if1.sh

 

[root@localhost shell]# cat if1.sh

 

#!/bin/bash

 

a=10

 

if [ $a -gt 4 ]

 

then

 

echo ok

 

fi

 

[root@localhost shell]# sh -x if1.sh   #执行脚本

 

+ a=10

 

+ '[' 10 -gt 4 ']'

 

+ echo ok

 

ok

 

[root@localhost shell]# sh -n if1.sh

 

4.2 带有else

 

基础结构:

 

if 判断语句 ; then

 

command

 

else

 

command

 

fi

 

示例如下:

 

[root@localhost shell]# vi if2.sh

 

[root@localhost shell]# cat if2.sh

 

#!/bin/bash

 

a=10

 

if [ $a -gt 4 ]

 

then

 

echo ok

 

else

 

echo "not ok"

 

fi

 

[root@localhost shell]# sh -x if2.sh    #执行脚本

 

+ a=10

 

+ '[' 10 -gt 4 ']'

 

+ echo ok

 

ok

 

4.3 带有elif

 

示例如下:

 

[root@localhost shell]# vi if3.sh

 

[root@localhost shell]# cat if3.sh

 

#!/bin/bash

 

a=3

 

if [ $a -gt 4 ]

 

then

 

echo ok

 

elif [ $a -gt 8 ]

 

then

 

echo "very ok"

 

else

 

echo "not ok"

 

fi

 

[root@localhost shell]# sh -x if3.sh   #执行脚本

 

+ a=3

 

+ '[' 3 -gt 4 ']'

 

+ '[' 3 -gt 8 ']'

 

+ echo 'not ok'

 

not ok

 

4.4 嵌套

 

示例如下:

 

[root@localhost shell]# vi if4.sh

 

[root@localhost shell]# cat if4.sh

 

#!/bin/bash

 

a=10

 

if [ $a -gt 4 ]

 

then

 

if [ $a -lt 20 ]

 

then

 

echo "ok"

 

else

 

echo "very ok"

 

fi

 

else

 

echo "not ok"

 

fi

 

[root@localhost shell]# sh -x if4.sh    #执行脚本

 

+ a=10

 

+ '[' 10 -gt 4 ']'

 

+ '[' 10 -lt 20 ']'

 

+ echo ok

 

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逻辑判断

 

if判断文件的目录属性

 

shell脚本中if经常用于判断文档的属性,比如判断是普通文件还是目录,判断文件是否有读、写、执行权限等。If常用选项如下:

 

-e:判断文件或目录是否存在。

 

-d:判断是不是目录以及是否存在。

 

-f:判断是不是普通文件以及是否存在。

 

-T:判断是否有读权限。

 

-w:判断是否有写权限。

 

-X:判断是否可执行。

 

4.7 shell中的case判断

 

case判断的基础格式如下:

 

case 变量 in

 

value1)          #不限制value的个数

 

command

 

;;

 

value2)

 

command

 

;;

 

)             #此处代表其他值

 

command

 

;;

 

esac

 

为了让我们能够更加 清晰的理解case逻辑判断,接下来我们编写一个脚本来进行实验

 

[root@localhost shell]# vi 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'

 

if [ -n "$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

 

 

echo "not ok"

 

;;

 

 

echo "ok"

 

;;

 

 

echo "very ok"

 

;;

 

 

echo "oook"

 

;;

 

*)

 

echo "The number range is 0-100."

 

;;

 

esac

 

执行结果;

 

[root@localhost shell]# sh case.sh 
Please input a number:1
not ok
[root@localhost shell]# sh case.sh 
Please input a number:81
very ok
[root@localhost shell]# sh case.sh 
Please input a number:66
ok
[root@localhost shell]# sh case.sh 
Please input a number:100
oook

 

5.shell中的循环

 

5.1 for循环

 

基础结构如下:

 

for 变量名 in 循环条件;

 

do

 

command

 

done

 

下面进行一个简单的实验演示,演示如下;

 

[root@localhost shell]# vi for1.sh

 

#!/bin/bash

 

sum=0

 

for i in seq 1 10

 

do

 

sum=sum+$i]

 

echo $i

 

done

 

echo $sum

 

执行结果;

 

[root@localhost shell]# sh for1.sh 
1
2
3
4
5
6
7
8
9
10
55

 

5.2 while循环

 

基础结构:
while 条件;do

 

command

 

done

 

示例1;

 

[root@localhost shell]# vi while1.sh
#!/bin/bash
while :               #此处冒号表示死循环
do
load=`w|head -1|awk -F 'load average:' '{print $2}'|cut -d. -f1`     #赋值给变量load
if [ $load -gt 10 ]
then
top|mail-s "load is high: $load" asldkfls011.com
fi
sleep 30
done

 

运行结果;

 

[root@localhost shell]# sh -x while1.sh 
+ :
++ w
++ head -1
++ awk -F 'load average:' '{print $2}'
++ cut -d. -f1
+ load=' 0'
+ '[' 0 -gt 10 ']'
+ sleep 30

 

示例2;

 

[root@localhost shell]# vim while2.sh
#!/bin/bash 
while :
do
  read -p "Please input a number: " n
  if [ -z "$n" ]
  then
      echo "you need input sth." 
      continue
  fi
  n1=`echo $n|sed 's/[0-9]//g '`
  if [ -n "$n1" ]
  then
      echo "you just only input numbers." 
      continue
  fi
  break
done
echo $n

 

运行结果;

 

[root@localhost shell]# sh while2.sh 
Please input a number: q
you just only input numbers.
Please input a number: 1
1
[root@localhost shell]# sh while2.sh 
Please input a number: 2
2
[root@localhost shell]# sh while2.sh 
Please input a number: 4444551
4444551

 

6.shell中的中断与继续

 

6.1 跳出循环

 

break 在脚本中表示跳出该层循环,示例如下

 

[root@localhost shell]# vim break1.sh
#!/bin/bash
for i in `seq 1 5`
do
   echo $i
   if [ $i -eq 3 ]
   then
       break
   fi
  echo $i 
done
echo aababab

 

执行结果;

 

[root@localhost shell]# sh break1.sh 
1
1
2
2
3
aababab

 

6.2 结束本次循环

 

当在shell脚本中使用continue时,结束的不是整个循环,而是本次循环。忽略continue之下的代码,直接进行下一次循环。

 

[root@localhost shell]#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

 

执行结果;

 

[root@localhost shell]# sh continue1.sh 
1
1
2
2
3
4
4
5
5
5

 

6.3 退出整个脚本

 

当我们在shell脚本中遇到exit时,其表示直接退出整个shell脚本。

 

[root@localhost shell]# 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@localhost 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中的函数

 

shell脚本中的函数就是先把一段代码整理到了一个小单元中,并给这个小单元命名,当我们用到这段代码时直接调用这个小单元的名字就可以了,这样很方便,省时省力。但我们需要注意,在shell脚本中,函数一定要写在前面,因为函数要被调用的,如果还未出现就被调用就会出错。

 

基础格式;

 

function f_name()
{
command
}

 

7.1 打印出第一个,第二个参数,参数的个数及脚本名

 

[root@localhost shell]# vi fun1.sh
#/bin/bash
input()
{
echo $1 $2 $# $0         # 函数的参数:$1 $2 $# ;$0则是脚本的名字
}
input 1 a b

 

执行结果;

 

[root@localhost shell]# sh fun1.sh 
1 a 3 fun1.sh
[root@localhost shell]# sh -x fun1.sh 
+ input 1 a b
+ echo 1 a 3 fun1.sh
1 a 3 fun1.sh

 

7.2 加法的函数

 

[root@localhost shell]# vi fun2.sh
#!/bin/bash
sum()
{
s=$[$1+$2]
echo $s
}
sum 1 2

 

执行结果;

 

[root@localhost shell]# sh -x fun2.sh 
+ sum 1 2
+ s=3
+ echo 3
3

 

7.3 获得一个网卡的IP地址

 

[root@localhost 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@localhost shell]# sh fun3.sh 
Please input the eth name: eth0   
eth0 address is 192.168.174.15
[root@localhost shell]# sh fun3.sh 
Please input the eth name: lo
lo address is 127.0.0.1

 

8. shell中的数组

 

8.1 数组读取

 

首先我们需要先定义一个数组a=(1 2 3 4 5);

 

命令 echo ${a[@]}读取数组中的全部元素。

 

[root@localhost shell]# a=(1 2 3 4 5 6 7 8)
[root@localhost shell]# echo ${a[@]}
1 2 3 4 5 6 7 8

 

命令 echo ${#a[@]} 获取数组的元素个数。

 

[root@localhost shell]# echo ${#a[@]}
8

 

命令 echo ${a[2]} 读取第三个元素,数组从0开始。

 

[root@localhost shell]# echo ${a[2]}
3

 

echo ${a[*]} 等同于 ${a[@]}  作用为显示整个数组。

 

[root@localhost shell]# echo ${a[*]}
1 2 3 4 5 6 7 8

 

8.2 数组赋值

 

a[1]=100; echo ${a[@]} 替换指定的元素值。

 

[root@localhost shell]# a[1]=100
[root@localhost shell]# echo ${a[@]}
1 100 3 4 5 6 7 8

 

a[5]=2; echo ${a[@]} 如果下标不存在则会自动添加一个元素

 

[root@localhost shell]# a[5]=2
[root@localhost shell]# echo ${a[*]}
1 100 3 4 5 2 7 8

 

a[7]=6; echo ${a[@]}  跳着添加元素时,中间未赋值的元素,不显示且无值。

 

[root@localhost shell]# a[7]=6
[root@localhost shell]# echo ${a[@]}
1 100 3 4 5 2 7 6

 

8.3 数组的删除

 

命令unset a[1] 用于删除单个元素。

 

 

 

[root@localhost shell]# echo ${a[@]}
1 3 4 5 2 7 6 6
[root@localhost shell]# echo ${a[7]}
6
[root@localhost shell]# unset a[7]
[root@localhost shell]# echo ${a[@]}
1 3 4 5 2 7 6

 

命令unset a 用于删除整个数组。

 

[root@localhost shell]# echo ${a[@]}
1 3 4 5 2 7 6
[root@localhost shell]# unset a
[root@localhost shell]# echo ${a[@]}

 

8.4 数组分片

 

在进行实验操作之前,需要对一个数组进行赋值 a=(seq 1 5) 。

 

命令echo ${a[@]:0:3} 表示从第一个元素开始,截取3个元素,并打印出来。

 

[root@localhost shell]# a=(`seq 1 5 `)
[root@localhost shell]# echo ${a[*]}
1 2 3 4 5
[root@localhost shell]# echo ${a[@]:0:3}
1 2 3

 

命令echo ${a[@]:1:4} 表示从第二个元素开始,截取4个元素

 

[root@localhost shell]# echo ${a[@]:1:4}
2 3 4 5

 

echo ${a[@]:0-3:2} 表示从倒数第3个元素开始,截取2个元素

 

[root@localhost shell]# echo ${a[@]:0-3:2}
3 4
[root@localhost shell]# echo ${a[@]:0-1:2}
5
[root@localhost shell]# echo ${a[@]:0-2:2}
4 5

 

8.5 数组替换

 

使用命令echo ${a[@]/b/100}  表示用100替换b,但不会保存替换

 

[root@localhost shell]# a=(a b c d e)
[root@localhost shell]# echo ${a[*]}
a b c d e
[root@localhost shell]# echo ${a[@]/b/100}
a 100 c d e

 

使用命令a=(${a[@]/b/100})  表示用100替换b,这种方法不仅可以打印出来还可以保存替换

 

[root@localhost shell]# a=(${a[@]/b/100})
[root@localhost shell]# echo ${a[*]}
a 100 c d e
posted @ 2022-05-06 17:45  王路飞飞飞  阅读(129)  评论(0)    收藏  举报