Linux Shell脚本编程基础
所属分类:Linux | 发布于 2022-10-24 11:11:29
1、概述
Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。
2、快速入门
2.1 脚本格式
脚本以#!/bin/bash开头(指定解析器),后面跟需要执行的命令,使用#注释
#!/bin/bash
echo "Hello World"
2.2 执行方式
脚本的执行方式通常有三种,加入当前目录是/home/alan/scripts,需要执行的脚本是/home/alan/scripts/helloworld.sh。
2.2.1 使用sh或bash + 脚本的相对路径或者绝对路径,这种方式不用给脚本加+x权限
sh + 脚本相对路径
[root@centos scripts]# sh ./helloworld.sh
sh + 脚本绝对路径
[root@centos scripts] # sh /home/alan/scripts/helloworld.sh
2.2.2 直接输入脚本的相对路径或者绝对路径来执行脚本,这种方式脚本必须可执行权限+x
[root@centos scrpits] # chmod +x helloworld.sh
[root@centos scripts] # /home/alan/scripts/helloworld.sh
2.2.3 在脚本路径前加“.” 或者 source执行。
[root@centos scripts]# source ./helloworld.sh
前面两种方式都是在当前shell中打开一个子shell来执行脚本内容,当脚本内容结束,则子shell关闭,回到父shell中。
第三种方式可以使脚本内容在当然shell里执行,而无需打开子shell!
开子shell和不开子shell的区别在于,环境变量的继承关系,如在子shell中设置的当前变量,在父shell中是不可见的。
2.3 解释器的种类
2.3.1 使用cat /etc/shells 查看当前系统所有shell解释器
alan@alans-MacBook-Pro demo % cat /etc/shells
/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
2.3.2 使用echo $SHELL输出当前默认的shell解释器
alan@alans-MacBook-Pro demo % echo $SHELL
/bin/zsh
3、变量
3.1 系统预定义变量
常见系统变量:$HOME、$PWD、$SHELL、$USER等
3.2 自定义变量
3.2.1 基本语法
定义变量:变量名=变量值,注意,=前后不能有空格
撤销变量:unset 变量名
声明静态变量:readonly变量,注意,不能unset
3.2.2 变量定义注意事项
1)、等号两侧不能有空格。
2)、在bash中,变量默认类型都是字符串类型,无法进行数值运算。
3)、变量的值如果有空格,需要使用双引号或单引号括起来。
[root@centos scripts] # D="I love bianliang"
[root@centos scripts] # echo $D
3.2.3 使用export可以吧变量提升为全局环境变量。
export 变量名
3.3 特殊变量
3.3.1 $n
$n,n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数需要用大括号括起来,如${10}
3.3.2 $#
$#,获取所有输入参数个数, 常用于循环,判断参数的个数是否正确以及加强脚本的健壮性。
3.3.3 $*, $@
$*,这个变量点命令行中所有的参数,$*把所有的参数看成一个整体。
$@,这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待。
3.3.4 $?
$?,最后一次执行的命令的返回状态。如果这个变量的值为0,则证明上一个命令正确执行;如果这个变量的指为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确。
4、运算符
4.1 基本语法
$((运算式))或$[运算式],其中小括号的话要连着两个,中括号的话只需要一个。
4.2 案例实操
计算(2+3) * 4的值
[root@centos scripts]# A=(((2+3)*4))
[root@centos scripts]# echo $A
[root@centos scripts]# B=[(2+3)*4]
[root@centos scripts]# echo $B
5、条件判断
5.1 基本语法
语法一):test condition
语法二):[ condition ] (注意condition前后要有空格)
5.2 常用判断条件
5.2.1 整数之间比较
-eq 等于(equal)
-ne 不等于(not equal)
-lt 小于 (less than)
-le 小于等于 (less equal)
-gt 大于 (greater than)
-ge 大于等于(greater equal)
5.2.2 字符串之间的比较
= 相等
!= 不相等
5.2.3 按照文件权限进行判断
-r 有读的权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)
5.2.4 按照文件类型进行判断
-e 文件存在(existence)
-f 文件存在并且是一个常规的文件(file)
-d 文件存在并且是一个目录(directory)
5.3 案例实操
5.3.1 23是否大于等于22
[root@centos scripts]# [ 23 -ge 22 ]
[root@centos scripts]# echo $?
0
5.3.2 helloworld.sh是否具有写权限
[root@centos scripts]# [ -w helloworld.sh ]
[root@centos scripts]# echo $?
0
5.3.3 判断/home/atguigu/cls.txt目录中的文件是否存在
[root@centos scripts]# [ -e /home/atguigu/cls.txt ]
[root@centos scripts]# echo $?
1
5.3.4 多条件判断(&&表示前一条命令执行成功时,才执行后一条命令,||表示上一条命令执行失败后,才执行下一条命令)
[root@centos scripts]# [ atguigu ] && echo OK || echo notOK
OK
[root@centos scripts]# [ ] && echo OK || echo notOK
notOK
6、流程控制
6.1 if判断
6.1.1 基本语法
1)单分支
if [ 条件判断式 ]; then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
2)多分支
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
注意事项:
1. [ 条件判断式 ],中括号和条件判断式之间必须有空格
2. if后要有空格
6.2 case语句
6.2.1 基本语法
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
...省略其它分支...
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
注意事项:
1)case行尾必须为单词"in",每一个模式匹配必须以右括号")"结束。
2)双分号";;"表示命令序列结束,相当于java中的break。
3)最后的"*)"表示模式模式,相当于java中的default。
6.3 for循环
6.3.1 基本语法1
for ((初始值; 循环控制条件; 变量变化))
do
程序
done
6.3.2 基本语法1实操,从1加到100
[root@centos scripts]# vi for1.sh
#!/bin/bash
sum=0
for((i=0;i<=100;i++))
do
sum=$[$sum+$i]
done
echo $sum
[root@centos scripts]# sh ./for1.sh
5050
6.3.3 基本语法2
for 变量 in 值1 值2 值3...
do
程序
done
6.3.4 基本语法2实操
[root@centos scripts]# vi for2.sh
#!/bin/bash
#打印数字
for i in cls mly wls
do
echo "i love $i"
done
[root@centos scripts]# sh ./for2.sh
i love cls
i love mly
i love wls
6.4 while循环
6.4.1 基本语法
while [ 添加表达式 ]
do
程序
done
6.4.2 案例实操,从1加到100
[root@centos scripts]# vi while.sh
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]
do
sum=$[$sum+$i]
i=$[$i+1]
done
echo $sum
[root@centos scripts]# sh ./while.sh
5050
7、函数
7.1 系统函数
7.1.1 basename
1)基本语法
basename [string / pathname] [suffix]
解释:basename函数会删掉所有的前缀包括最后一个“/”,然后将字符串显示出来,可以简单理解为取路径里的文件名称。
选项:
suffix为后缀,如果suffix被指定了,basename会将去掉。
2)案例实操
截取/home/alan/scripts/helloworld.txt我文件名称
[root@centos scripts]# basename /home/alan/scripts/helloworld.txt
helloworld.txt
[root@centos scripts]# basename /home/alan/scripts/helloworld.txt .txt
helloworld
7.1.2 dirname
1)基本语法
dirname 文件绝对路径
解释:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分),可以简单理解为取文件路径的绝对路径名称。
2)案例实操
获取文件helloworld.txt的路径
[root@centos scripts] dirname /home/alan/scripts/helloworld.txt
/home/alan/scripts
7.2 自定义函数
7.2.1 基本语法
[function] funcname[()]
{
action;
[return int;]
}
7.2.2 主要事项
1)先声明后调用,必须在调用函数之前,先声明函数,shell脚本是逐行执行的,不像其它语言一样先编译。
2)函数返回值,只能通过$?系统变量获得,可以显示加return 返回;如果不加,将以最后一条命令运行结果,,作为返回值。return后跟数值n(0-255)。
7.2.3 案例实操
计算两个输入参数的和。
[root@centos scripts]# vi func.sh
#!/bin/bash
function sum()
{
s=0
s=$[$1+$2]
echo "$s"
}
read -p "Please input the number1:" n1;
read -p "Please input the number2:" n2;
sum $n1 $n2;
[root@centos scripts]# chmod +x func.sh
[root@centos scripts]# ./func.sh
Please input the number1:2
Please input the number2:5
7