Shell编程

[toc]

1. Shell简介

​ Shell 是一个命令行解释器,它为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序.

  • image-20200204231318400

2. Shell脚本格式要求

  • 脚本以 # !/bin/bash 开头
  • 脚本需要有可执行权限

3. Shell的变量

Linux Shell 中的变量分为,系统变量和用户自定义变量。

  • 系统变量:$HOME、$PWD、$SHELL、$USER 等等

myShell.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 #!/bin/bash
echo "Hello shell!"

#输出系统变量
echo "PATH=$PATH"
echo "USER=$USER"

A=100
echo "A=$A"
#撤销变量unset
unset A
echo "A=$A"

#静态readonly变量不能unset
readonly B=200
echo "B=$B"
unset B
echo "B=$B"

#变量名不能数字开头
#等号两边不能有空格
A=19
MYNUM=89
echo "$A $MYNUM"
5A=11
#将命令的返回值赋给变量
RESULT=`ls -l /root`
echo $RESULT
echo ""
MY_DATE=$(date)
echo "date=$MY_DATE"

:>>!
多行注释
!

4. Shell的位置参数

当我们执行一个 shell 脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量。

positionPara.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
#获取到各个参数

#$0==positionPara.sh
echo "$0 $1 $2"

#这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
echo "$*"

#这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
echo "$@"
#$*和$@在循环的时候就知道区别了!

#这个变量代表命令行中所有参数的个
echo "$#"

5. Shell的预定义变量

shell 设计者事先已经定义好的变量,可以直接在 shell 脚本中使用

preVar.sh

1
2
3
4
5
6
#!/bin/bash
echo "当前进程号=$$"
#后台的方式运行 myShell.sh
./myShell.sh &
echo "最后的进程号=$!"
echo "执行的结果$?"

6. Shell的运算符

demo.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash

#第一种方式$()
RESULT1=$(((2+3)*4))
echo "result1=$RESULT1"

#第二种方式[]
RESULT2=$[(2+3)*4]
echo "result2=$RESULT2"

#第三中方式 expr
TEMP=`expr 2 + 3`
RESULT3=`expr $TEMP \* 4`
echo "result3=$RESULT3"

#求出两个参数的和
SUM=$[$1+$2]
echo "SUM=$SUM"

7. Shell的条件判断

两个整数的比较

  • = 字符串比较
  • -lt 小 于
  • -le 小于等于
  • -eq 等 于
  • -gt 大 于
  • -ge 大于等于

judge.sh

  • if
  • then
  • fi

按照文件权限进行判断

  • -r 有读的权限 [ -r 文件 ]
  • -w 有写的权限
  • -x 有执行的权限

按照文件类型进行判断

  • -f 文件存在并且是一个常规的文件
  • -e 文件存在
  • -d 文件存在并是一个目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
#案例一:"ok"是否等于"ok"

if [ "ok" = "ok" ]
then
echo "√"
fi



#案例二:23 是否大于等于 22
if [ 23 -ge 22 ]
then
echo "大于"
fi

#案例三:/root/shell/aaa.txt 目录中的文件是否存
if [ -e /root/file/shell/aaa.txt ]
then
echo "存在"
fi

8. Shell的流程控制

8.1 If判断

testIf.sh

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

#案例:请编写一个 shell 程序,如果输入的参数,大于等于 60,
则输出 "及格了",如果小于 60,则输出 "不及格"

if [ $1 -ge 60 ]
then
echo "及格了"
elif [ $1 -lt 60 ]
then
echo "不及格"
fi

8.2 Case语句

注意Case语句的格式!

testCase.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
#案例一:当命令行参数是 1 时,输出 "周一", 是 2 时,就
输出"周二", 其它情况输出 "other"


case $1 in
"1")
echo "星期一"
;;
"2")
echo "星期二"
;;
"3")
echo "星期三"
;;
"4")
echo "星期四"
;;
"5")
echo "星期五"
;;
*)
echo "星期天"
;;
esac

8.3 For循环

testFor.sh

testFors.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
#案例 1 :打印命令行输入的参数 【会使用到$* $@

for i in "$*"
do
echo "the num is $i"
done

echo "================="

for j in "$@"
do
echo "the num is $j"
done

#结果如下:
[root@DuanChaojie shell]# sh testFor.sh 10 20 30
the num is 10 20 30
=================
the num is 10
the num is 20
the num is 30
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
#案例 1 :从 1 加到 100 的值输出显示

#定义一个变量
SUM=0

for ((i=1;i<=100;i++))
do
SUM=$[$SUM+$i]
done
echo "sum=$SUM"

8.4 while循环

testWhile.sh

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
#案例 1 :从命令行输入一个数 n,统计从 1+..+ n 的值是多少?

SUM=0
i=0
while [ $i -le $1 ]
do
SUM=$[$SUM+$i]
i=$[$i+1]
done
echo "sum=$SUM"

9. Shell的read读取控制台输入

testRead.sh

read

  • -p 指定读取值时的提示符;

  • -t 指定读取值时等待的时间(秒),如果没有在指定的时间内输入,就不再等待了。

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

#案例 1:读取控制台输入一个 num 值

read -p "请输入一个数num1=" NUM1
echo "第一次输入的数是: $NUM1"


#案例 2:读取控制台输入一个 num 值,在 10 秒内输入。
read -t 5 -p "请输入第二个数num2="NUM2
echo "第二次输入的值是:$NUM2"

10. Shell的函数

shell 编程和其它编程语言一样,有系统函数,也可以自定义函数。系统函数中,我们这里就介绍两个。

10.1 Shell的系统函数

basename [pathname] [suffix]

  • 返回完整路径最后 / 的部分,常用于获取文件名

dirname [string] [suffix]

  • 返回完整路径最后 / 的前面的部分,常用于返回路径部分

10.2 Shell的自定义函数

shellFun.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
#两个系统函数

basename==得到的是文件名

dirname ==得到的是文件的路径

#自定义函数
function getSum(){
SUM=$[$n1+$n2]
echo "和是=$SUM"
}
read -p "请输入第一个数n1" n1
read -p "请输入第二个数n2" n2

#调用getSum
getSum $n1 $n2