【Shell】3万字图文讲解带你快速掌握shell脚本编程

8 篇文章 1 订阅

1、快速入门

1.1、Shell介绍

shell就是人机交互的一个桥梁 ;shell 本质上是 linux 命令,一条一条命令组合在一起,实现某一个目的,就变成了shell脚本。它从一定程度上 减轻了工作量,提高了工作效率。

官方概念:

Shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出,简单来说Shell就是一个用户跟操作系统之间的一个命令解释器。

1.2、Shell编程需知

  • 命名规范:
    • 文件名一般为大小写英文、数字、-、_组成,但要记得见名知意
    • Shell脚本文件后缀名均为.sh
    • 编写Shell脚本时必须以#!/bin/bash做为首行来指定解释器

1.3、编写第一个Shell脚本

创建HelloWorld.sh

[root@node100 shell_test]# vim HelloWorld.sh

编写内容

#!/bin/bash
echo 'Hello World!!!'
# echo 为打印输出

执行脚本文件

① 给文件执行权限

[root@node100 shell_test]# chmod +x HelloWorld.sh 

②执行脚本

# 相对路径执行
[root@node100 shell_test]# ./HelloWorld.sh 

# 绝对路径执行
[root@node100 shell_test]# /shell_test/HelloWorld.sh 

注意:bash中的引号

双引号"" :会把引号的内容当成整体来看待,允许通过$符号引用其他变量值

单引号'' :会把引号的内容当成整体来看待,禁止引用其他变量值,shell中特殊符号都被视为普通字符 

反撇号`` :反撇号和$()一样,引号或括号里的命令会优先执行,如果存在嵌套,反撇号不能用

1.4、注释

在编译过程中被解释器忽略的内容就称为注释。

单行注释

单行注释格式: 
    # 这是一个注释

多行注释

多行注释格式:
    :<<EOF
 注释内容...
 注释内容...
 注释内容...
    EOF 
说明:EOF 也可以使用其他符号

2、变量

变量是用来临时保存数据的,该数据是可以变化的数据。

2.1、变量定义

定义语法:变量名=变量值

①定义变量

[root@node100 shell_test]# a=123

②调用变量

[root@node100 shell_test]# echo $a
或者
[root@node100 shell_test]# echo ${a}

③删除变量

[root@node100 shell_test]# unset a

以上变量用法在Shell脚本中也同样使用

2.2、变量的定义规则

①变量名区分大小写

②变量名不能有特殊符号

特别说明:对于有空格的字符串给变量赋值时,要用引号引起来;

③变量名不能以数字开头但可以包含数字

④等号两边不能有任何空格

⑤变量名尽量做到见名知意

2.3、变量的定义方式

①直接赋值给一个变量

[root@node100 shell_test]# a=123456789
[root@node100 shell_test]# echo ${a:2:3}   # 表示从第3位开始截取,截取3个字符
345

说明:

$变量名${变量名}的异同

相同点:相同点:都可以调用变量

不同点:${变量名}可以只截取变量的一部分,而$变量名不可以

②命令执行结果赋值给变量

[root@node100 shell_test]# a=`hostname`
[root@node100 shell_test]# echo $a
node100
[root@node100 shell_test]# b=$(date)
[root@node100 shell_test]# echo $b
2022年 07月 30日 星期六 13:59:22 KST

③交互式定义变量(read)

目的:让用户自己给变量赋值,比较灵活。

语法:read [选项] 变量名 

常见选项

选项解释
-p定义提示用户的信息
-n定义字符数(现在变量长度)
-s不显示(不显示用户的密码)
-t定义超时时间,默认单位为秒(现在用户输入变量值的超时时间,单位为秒)

举例1:让用户自己定义变量值

[root@node100 shell_test]# read -p "请输入你的名字" name

[root@node100 shell_test]# read -n6 a

[root@node100 shell_test]# read -s pwd

[root@node100 shell_test]# read -t1 a

举例2:变量值来自文件

注意:无论文件有多少内容,默认只取第一行内容作为变量值。

④定义有类型的变量(declare)

目的:给变量做一些限制,固定变量的类型,比如:整型、只读

用法:declare 选项 变量名=变量值

常用选项:

选项解释举例
-i将变量看成整数declare -i A=123
-r定义只读变量declare -r B=hello
-a定义普通数组;查看普通数组
-A定义关联数组;查看关联数组
-x将变量通过环境导出declare -x A=123456 等于 export A=123456

举例:

凡是被-i选项修饰的变量,只能赋值整数。

凡是被-r选项修饰的变量,为只读变量不能修改。

2.4、系统变量

系统变量(内置bash中变量) : shell本身已经固定好了它的名字和作用.

内置变量含义
$?返回上一条命令的执行状态;0表示执行正常,非0表示执行异常或错误
$0当前执行的程序和脚本名
$#脚本后面接的参数的个数
$*脚本后面所有参数,参数当成一个整体输出,每一个变量参数之间以空格隔开
$@脚本后面所有参数,参数是独立的,也是全部输出
$1-$9脚本后面的位置参数,$1表示第一个位置参数,以此类推
${10}-${n}扩展位置参数,第10个位置变量必须用{}大括号括起来(2位数字以上括起来)
$$先前所在进程的进程号
$!后台运行的最后一个进程号
!$调用最后一条命令历史中的参数

2.5、变量扩展

求变量长度:${#变量名}

[root@node100 shell_test]# q=123
[root@node100 shell_test]# echo ${#q}

替换:${变量/old/new}将变量中第一次出现的old值替换成new值

[root@node100 shell_test]# url=www.baidu.com
[root@node100 shell_test]# echo ${url/w/x}

替换:${变量//old/new}将变量中出现的old值全部替换成new值

[root@node100 shell_test]# echo ${url//w/x}

3、简单四则运算

算术运算:默认情况下,shell就只能支持简单的整数运算

运算内容:加(+)、减(-)、乘(*)、除(/)、求余数(%)

3.1、四则运算符号

表达式举例
$(())echo $((1+1))
$[]echo $[10-5]
exprexpr 10 / 5
letn=1;let n+=1等价于let n=n+1

注意:在使用expr时一定要注意空格,而且在做乘法运算时一定要加引号,因为*在Linux中表示通配符。

$(())

$[]

expr

let

3.2、i++++i

i++:先打印i,后进行加1操作

++i:先进行加1操作,后打印i

注意:除了i++++i外,i----i;expr不支持i++++i

4、数组

4.1、普通数组

①一次赋予一个值

数组名[索引下标]=值

[root@node100 shell_test]# qwe[0]=1
[root@node100 shell_test]# qwe[1]=2
[root@node100 shell_test]# qwe[2]=3

访问:${数组名[元素下标]}

[root@node100 shell_test]# echo ${qwe[0]}

也可以通过declare -a 数组名的方式去声明数组

②一次赋予多个值

数组名=(值1 值2 值3 ...)

[root@node100 shell_test]# asd=(v1 v2 v3)

访问:${数组名[元素下标]}

[root@node100 shell_test]# echo ${asd[0]}

③将文件中每一行赋值给数组

[root@node100 shell_test]# cat 1.txt
qwe
asd
zxc
rty
[root@node100 shell_test]# zxc=(`cat 1.txt`)

访问:${数组名[元素下标]}

[root@node100 shell_test]# echo ${zxc[0]}

4.2、关联数组

①声明关联数组

声明方式:declare -A 数组名

[root@node100 shell_test]# declare -A array

②数组赋值

一次赋一个值

语法:数组名[索引or下标]=变量值

[root@node100 shell_test]# array[hello]=world

访问数组中的值

语法:echo ${数组名[索引or下标]}

一次赋多个值

语法:数组名=([下标1]=变量值1 [小标2]=变量值2 ... ...)

[root@node100 shell_test]# declare -A array2
[root@node100 shell_test]# array2=([1]=one [name]=tom [age]=18)

访问

语法:echo ${数组名[索引or下标]}

[root@node100 shell_test]# echo ${array2[1]}

访问数组中全部数据

[root@node100 shell_test]# echo ${array2[*]}

访问数组中的全部下标或索引名词

[root@node100 shell_test]# echo ${!array2[*]}

5、条件判断

5.1、条件判断语法格式

格式1: test 条件表达式

格式2: [ 条件表达式 ] 

格式3: [[ 条件表达式 ]]

5.2、条件判断相关参数

可以判断文件类型,判断文件新旧,判断字符串是否相等,判断权限等等..

①判断文件类型

判断参数含义
-e判断文件是否存在
-f判断文件是否存在并且是一个普通文件
-d判断文件是否存在并且是一个目录
-L判断文件是否存在并且是一个软连接文件
-b判断文件是否存在并且是一个块设备文件
-S判断文件是否存在并且是一个套接字文件
-c判断文件是否存在并且是一个字符设备文件
-p判断文件是否存在并且是一个命名管道文件
-s判断文件是否存在并且是一个非空文件(有内容)

举例:test 条件表达式

[root@node100 shell_test]# test  -e a
[root@node100 shell_test]# echo $?

举例:[ 条件表达式 ] 

[root@node100 shell_test]# [ -e 1.txt ]
[root@node100 shell_test]# echo $?

举例:[[ 条件表达式 ]]

[root@node100 shell_test]# [[ -e 1.txt ]]
[root@node100 shell_test]# echo $?

②判断文件权限

判断参数含义
-r当前用户对其是否可读
-w当前用户对其是否可写
-x当前用户对其是否可执行
-u是否有suid,高级权限冒险位
-g是否有sgid,高级权限强制位
-k是否有t位,高级权限粘滞位

举例:

[root@node100 shell_test]# [ -r 1.txt ]
[root@node100 shell_test]# echo $?

[root@node100 shell_test]# [ -x 1.txt ]
[root@node100 shell_test]# echo $?

③判断文件新旧

说明:这里的新旧指的是文件的修改时间。

判断参数含义
file1 -nt file2比较file1是否比file2新
file1 -ot file2比较file1是否比file2旧
file1 -ef file2比较是否为同一个文件

举例:

[root@node100 shell_test]# [ 1.txt -nt demo1.sh ]
[root@node100 shell_test]# echo $?

④判断整数

判断参数含义
-eq相等
-ne不等
-gt大于
-lt小于
-ge大于等于
-le小于等于

举例:

[root@node100 shell_test]# [ 1 -eq 1 ]
[root@node100 shell_test]# echo $?

⑤判断字符串

判断参数含义
-z判断是否为空字符串,字符串长度为0则成立
-n判断是否为非空字符串,字符串长度不为0则成立
string1 = string2判断字符串是否相等
string1 != string2判断字符串是否不相等

举例:

[root@node100 shell_test]# [ a = a ]
[root@node100 shell_test]# echo $?

⑥多重条件判断

判断符号含义举例
-a和&&逻辑与[ 1 -eq 1 -a 1 -ne 0 ]或者[ 1 -eq 1 ] && [ 1 -ne 0 ] 
-o逻辑或[ 1 -eq 1 -o 1 -ne 0 ]

特别说明:

&& 前面的表达式为真,才会执行后面的代码

|| 前面的表达式为假,才会执行后面的代码

[root@node100 shell_test]# [ 2 -eq 2 ] && echo 'true'

[root@node100 shell_test]# [ 2 -eq 1 ] && echo 'true'||echo 'false'

5.3、类C风格的数值比较

注意:在(( ))中,=表示赋值;==表示判断

举例:

注意:;只用于分割命令或表达式

6、流程控制语句

6.1、if语句

语法结构:

① if结构

if condition
then
    command1 
    command2
    ...
    commandN 
fi

② if...else结构

if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi

③ if...elif...else结构

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

举例:

编写if.sh文件

#!/bin/bash
read -p "请输入你的年龄" age
if [ $age -ge 1 -a  $age -le 18 ]
then
	echo "年龄大于等于1并且小于等于18是未成年人"
elif [[ $age -gt 18 ]]
then
	echo "年龄大于18是成年人"
else
	echo "请输入正确的年龄"
fi

执行if.sh文件

[root@node100 shell_test]# chmod +x if.sh 
[root@node100 shell_test]# ./if.sh 

6.2、case语句

语法结构

case 变量名 in            
变量值1)              
    command1            需要执行的语句
    ;;                  两个分号代表命令结束
变量值2)
    command2
    ;;
变量值3)
    command3
    ;;
 *)              default,不满足以上模式,默认执行*)下面的语句
    command4
    ;;
esac  

举例:

编写case.sh文件

#!/bin/bash
read -p "请输入变量值" i
case $i in
	1)
		echo "你是第一名"
		;;
	2)
		echo "你是第二名"
		;;
	3)
		echo "你是第三名"
		;;
	*)
		echo "你不是前三名"
		;;
esac

执行

[root@node100 shell_test]# chmod +x case.sh 
[root@node100 shell_test]# ./case.sh 

6.3、for循环语句

语法结构:

①列表循环

列表for循环:用于将一组命令执行已知的次数 
基本语法格式 
for variable in {list}
do 
    command 
    command 
 … 
done 
或者
for variable in a b c 
do 
    command 
    command 
done 

举例(控制台):

[root@node100 shell_test]# for i in {1..10};do echo $i;done

[root@node100 shell_test]# for i in 1 2 3;do echo $i;done

\

[root@node100 shell_test]# for i in {1..10..2};do echo $i;done
# {起始值..结束值..步长}

[root@node100 shell_test]# for i in {10..1..2};do echo $i;done

[root@node100 shell_test]# for i in $(seq 10);do echo $i;done
# seq是个命令 seq [起始值] [步长] [结束值]

②不带列表循环

for variable 
do 
    command 
    command 
 … 
done 

举例:

编写for1.sh

#!/bin/bash
for i 
do
	echo $i
done

在执行的传参

[root@node100 shell_test]# chmod +x for1.sh 
[root@node100 shell_test]# ./for1.sh 1 2 3 

③类C风格的for循环

for(( expr1;expr2;expr3 )) 
do 
    command 
    command 
 … 
done 
# expr1:初始条件 
# expr2:循环条件 
# expr3:迭代条件

举例:

编写for2.sh文件

#!/bin/bash
for((i=1;i<=5;i++))
do
	echo $i
done

执行

[root@node100 shell_test]# chmod +x for2.sh 
[root@node100 shell_test]# ./for2.sh 

6.4、while循环语句

特点:条件为真就进入循环;条件为假就退出循环

语法结构:

while 表达式 
do 
	command... 
done 

举例:

编写while.sh文件

#!/bin/bash
i=1
while ((i<=5)) # ((i<=5)) 也可以换成 [ $i -le 5 ]
do
	echo $i
	let i++
done

执行

[root@node100 shell_test]# chmod +x while.sh 
[root@node100 shell_test]# ./while.sh 

6.5、until循环

特点:条件为假就进入循环;条件为真就退出循环

语法结构

until expression
    do 
    command 
    command 
    ... 
done

举例:

编写until.sh文件

#!/bin/bash
i=1
until [ $i -gt 5 ]
do
	echo $i
	let i++
done

执行

[root@node100 shell_test]# chmod +x until.sh 
[root@node100 shell_test]# ./until.sh

6.6、循环控制语句

continue:继续;表示循环体内下面的代码不执行,重新开始下一次循环

break:打断;马上停止执行本次循环,执行循环体后面的代码

exit:表示直接跳出程序

举例:循环打印1-5,但不打印3

编写continue.sh

#!/bin/bash
for((i=1;i<=5;i++))
do
	if ((i==3))
	then
		continue
	fi

	echo $i
done

执行

[root@node100 shell_test]# vim continue.sh 
[root@node100 shell_test]# ./continue.sh 

举例:循环打印1-5,但是但是打印到3的时候结束循环

编写break.sh文件

#!/bin/bash
for((i=1;i<=5;i++))
do
	echo $i
	if ((i==3))
	then
		break
	fi
done

echo "程序结束"

执行

[root@node100 shell_test]# chmod +x break.sh 
[root@node100 shell_test]# ./break.sh

举例:循环打印1-5,但是但是打印到3的时候结束整个程序

编写exit.sh文件

#!/bin/bash
for((i=1;i<=5;i++))
do
	echo $i
	if ((i==3))
	then
		exit
	fi
done
echo "结束程序"

执行

[root@node100 shell_test]# vim exit.sh 
[root@node100 shell_test]# ./exit.sh

7、函数

7.1、函数概述

shell中允许将一组命令集合或语句形成一段可用代码,这些代码块称为shell函数,给这段代码起个名字称为函数名,后续可以直接调用该段代码的功能。

7.2、定义函数

语法结构

[ function ] 函数名(){
 命令代码
	[ return [value]]
	# 在return后面写一个值(0-256) 然后通过 echo $? 查看状态值。
	# 若只写return则表示结束,return后面的代码将不会执行
 命令代码
}

举例:编写求输入参数和的函数

编写fun.sh文件

#!/bin/bash
function get_sum(){
	 sum=0
	for i in $@
	do
		let sum+=i
	done
	return $sum # 也可以直接 echo
}

执行

[root@node100 shell_test]# source fun.sh  # 生效文件
[root@node100 shell_test]# get_sum 1 2 3 # 调用函数并传参
[root@node100 shell_test]# echo $?        # 查看状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值