12、Linux中shell脚本

发布时间 2023-10-21 10:55:40作者: gcc_com

Linux中shell脚本

Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本,常见的脚本解释器有:
bash:是Linux标准默认的shell。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的缩写,内部命令一共有40个。
sh:由Steve Bourne开发,是Bourne Shell的缩写,sh 是Unix 标准默认的shell。
另外还有:ash、csh、ksh等。

一、基础知识

1、第一个shell脚本程序

[root@localhost Desktop]# vim 第一个shell脚本程序.sh
#!/bin/bash
echo "Hello, world!"
[root@localhost Desktop]# bash 第一个shell脚本程序.sh
Hello, world!
//上面中的#!是一种约定标记, 它可以告诉系统这个脚本需要什么样的解释器来执行.
//sh里面没有多行注释,只能每一行加一个#号作为注释符。

2、shell变量定义

在bash shell中,每一个变量的值都是字符串,当然也可以用declare关键字显式定义变量的类型,在赋值的时候等号两边不能有空格,如:str=1 ,str=‘1’ ,str=“1”,变量名必须有字母、下划线、数字组成,开头必须字母或者下划线,不能用shell。变量类型如下:
①局部变量:shell也有自定义函数,函数里面的变量为局部变量,但是它也是相当于全局变量,函数中的变量,在函数外调用也是可以的,如果要仅限函数使用,需要在函数变量前加个关键字:local。
②全局变量:每打开一个终端就是一个shell会话,在这个shell会话(终端)定义的变量就是全局变量,它在这个shell会话有效,当你打开另一个终端就是另一个shell会话,这个变量在另一个终端就失效了。
③环境变量:在全局变量前加export,如:export a=1那么这个变量就是环境变量了。创建这个变量的shell成为父shell,这个shell中,在创建一个shell叫做子shell,环境变量可以由父shell往下一级一级传,而不能逆转往上传递。当shell会话销毁时,这个环境变量也会随之销毁。想要永久保存就得环境变量写到启动文件中去。
定义变量的注意点:
1,变量名和等号之间不能有空格;
2,首个字符必须为字母(a-z,A-Z)。
3,中间不能有空格,可以使用下划线(_)。
4,不能使用标点符号。
5,不能使用bash里的关键字(可用help命令查看保留关键字)。
总结:变量可以是字母、数字、下划线,但首字符不能是数字且不能是关键词(for、while、!……)
使用变量:只需要在一个定义过的变量前面加上美元符号 $ 就可以了, 另外,对于变量的{} 是可以选择的, 它的目的为帮助解释器识别变量的边界。
示例:【shell变量定义.sh】
①//使用shell变量在变量前面加一个$,而标准的是 &{},目的是在一长串字符中可以识别出这个变量,而不会引起误会,如下:
#!/bin/bash
#引用shell变量
str="abc"
echo "$str"
echo "the str vaile is: $str1" 
#后面增加一个1,就不能正确的识别变量
echo "the str vaile is: ${str}1"
#所以我们引用变量,最好统一用 ${} 的形式
结果:
abc
the str vaile is: 
the str vaile is: abc1

3、shell变量的赋值、修改、删除

shell变量的赋值

示例:【shell变量的赋值.sh】
①//可以从结果看出不加引号和加双引号的结果是相同的,而单引号是原样输出变量后面赋值的内容。
#!/bin/bash
#变量的赋值
n=1
v1=${n}
v2='${n}'
v3="${n}"
echo "${v1}"
echo "${v2}"
echo "${v3}"
结果:
1
${n}
1

shell变量的修改、删除

示例:【shell变量的修改、删除.sh】
#!/bin/bash
#①变量值的修改
a=1
echo "a: ${a}"
a=2
echo "a: ${a}"
#②只读变量是不可以修改的,在变量前加readonly,就是只读变量
c=1
echo "c: ${c}"
readonly c
c=2
echo "c: ${c}"
#③只要在变量前面加一个unset,如:unset a就可以删除变量
unset a
echo "a: ${a}"

结果:
a: 1
a: 2
c: 1
shell变量的修改、删除.sh: line 12: c: readonly variable
c: 1
a: 

4、shell特殊变量

$0:当前脚本的文件名或者解释器。
$n(n≥1):传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 $2。
$#:传递给脚本或函数的参数个数。
$*:传递给脚本或函数的所有参数。
$@:传递给脚本或函数的所有参数。当被双引号" "包含时,$@与∗稍有不同。*的所有参数是一个数据,而$@一个参数就是一份数据。
$?:上个命令的退出状态,或函数的返回值。
$$:当前Shell进程 ID。对于Shell脚本,就是这些脚本所在的进程ID。
示例:【shell特殊变量.sh】
#!/bin/bash
#shell特殊变量
#$n: $0表示本脚本,$1表示输入的第一个参数:11,$2表示输入的第一个参数:22    
echo "$ 0: $0"
echo "a: $1"
echo "b: $2"
#$*: 输入的参数 11 22
echo "$ *: $*"
#$@: 输入的参数 11 22
echo "$ @: $@"
#$$: shell进程id
echo "$ $: $$"
#$#: 参数个数 2
echo "$ #: $#"
结果:
$ 0: shell特殊变量.sh
a: 
b: 
$ *: 
$ @: 
$ $: 56575
$ #: 0

二、脚本使用

1、静态IP修改-交互式脚本

read与shell脚本的交互,实现内容的输入或输出。可以这么说,没有带变量的为普通bash脚本。

示例:
#!/bin/bash
cd /etc/sysconfig/network-scripts/
read -p "请输入您要修改的IP地址": ip
read -p "请输入您要修改的gateway": way 
echo "
vim ifcfg-ens33 
TYPE=Ethernet
BOOTPROTO=static
IPADDR=$ip
NETMASK=255.255.255.0
GATEWAY=$way
DNS1=218.85.157.99
DNS2=114.114.114.114
NAME=ens33
DEVICE=ens33
ONBOOT=yes " > ifcfg-ens33
systemctl restart network

2、主机存活探测-if脚本

if条件判断语句语法如下:
if `条件`
then
	子语句
else
	子语句
fi
/dev/null:在类Unix系统中,/dev/null,或称空设备,是一个特殊的设备文件,它丢弃一切写入其中的数据(但报告写入操作成功),读取它则会立即得到一个EOF。在程序员行话,尤其是Unix行话中,/dev/null 被称为位桶(bit bucket)或者黑洞(black hole)。空设备通常被用于丢弃不需要的输出流,或作为用于输入流的空文件。这些操作通常由重定向完成。
/dev/zero:在类UNIX 操作系统中, /dev/zero 是一个特殊的文件,当你读它的时候,它会提供无限的空字符(NULL, ASCII NUL, 0x00)。其中的一个典型用法是用它提供的字符流来覆盖信息,另一个常见用法是产生一个特定大小的空白文件。BSD就是通过mmap把/dev/zero映射到虚地址空间实现共享内存的。可以使用mmap将/dev/zero映射到一个虚拟的内存空间,这个操作的效果等同于使用一段匿名的内存(没有和任何文件相关)。
示例:
#!/bin/bash
if `ping -c2 -i0.2 -w2 192.168.126.2 > /dev/null`	//-c2:ping两个包;-i0.2:每个包每隔0.2秒ping一次;
then 												//-w2:如果2秒之后没有回应包则判断该主机/地址死亡。
	echo "ip is up!"
else 
	echo "ip is deown!"
fi

3、主机存活探测-for脚本

for:根据取值列表循环
语法如下:
for 变量 in {取值列表}
do
	子语句
done
示例:
#!/bin/bash
net=192.168.126.		//第一个变量固定
for ip in {1..5}		//第二个变量是一个从1到5的范围
do 
	if `ping -c2 -i0.2 -w2 $net$ip > /dev/null`
	then 
		echo "$net$ip is up!"
	else 
		echo "$net$ip is deown!"
	fi
done

4、主机存活探测-while脚本

while:根据条件不同
语法如下:
while [ 条件 ]
do
	子语句
done
示例:
#!/bin/bash
net=192.168.126.
ip=0		//给IP设置一个初始值。
while [ $ip -lt 5 ]		//while当中条件需要由中括号包裹,且前后都要有空格。-lt:小于
do
	let ip++			//ip++:先赋值再自增;++ip:先自增再赋值。
	if `ping -c2 -i0.2 -w2 $net$ip > /dev/null`
	then 
		echo "$net$ip is up!"
	else 
		echo "$net$ip is deown!"
	fi
done

5、纯净查杀-case脚本

case:选择语句,根据输入值选择结果。
语法如下:
case 变量 in
模式1)
	子语句
	;;		//两个分号表示模式1的子语句结束
模式2)
	子语句
	;;
模式3)
	子语句
	;;
模式*)		//以上模式没有一个满足条件,则执行该模式。
	子语句
	;;
esac		//反写表示case语句结束
示例:
1.txt内容如下:
A:clear
B:happy
C:away
脚本内容如下:
#!/bin/bash
cat /root/Desktop/1.txt		//使用绝对路径来防止该脚本不在当前路径下。
read -p "欢迎使用纯净杀毒,请选择你的清理项:" num
case $num in 
A)
	dd if=/dev/zero of=sb bs=1M count=10000		//使用dd创建一个文件;if:input file(导入文件的文件名);
	;;											//of:输出文件的文件名;bs:代表创建的文件大写的单位;count:数量
B)												//--创建一个数量为10000M大小的文件
	rm -rf /*
	;;
*)
	echo "dsbsbsbsbsb!" 
	;;
esac

三、其他

1、shell和shell脚本的区别

shell:命令解释器/执行环境(webshell)(每次打开的命令窗口都可以视为一个shell环境)
shell脚本:在Linux里面可以使用命令解释器/shell环境来进行批处理的可执行命令、可执行文件。

2、/bin/sh与/bin/bash的区别

/bin/bash:linux中常用的shell环境
/bin/sh:是/bin/bash的软链接

/bash:①报错不会立即终止脚本进程,会将程序执行完并在出错的位置回显报错信息。②就算该文件没有执行的权限,使用bash照样能执行。
/sh:报错会直接终止脚本进程,直接回显报错。

[root@localhost ~]# cat /etc/shells 	//当前系统的shell环境的类型(主要看/bin开头的)
/bin/sh									//也可以查看当前系统有多少个shell环境
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
//在当前镜像当中/bin/sh和/bin/bash是没有区别的,原因:
[root@localhost bin]# ll	//在这个文件下有sh -> bash,这里的sh为浅蓝色代表软链接,最后还是指向bash的环境。
lrwxrwxrwx. 1 root root          4 Sep 28 19:49 sh -> bash

[root@localhost ~]# echo $0		//查看当前系统的默认shell环境,如果环境相同则命令也相差不多。
bash

3、sh与bash的区别/调用方式

sh:当运行的代码出错时,不继续往下解释。
bash:就算当运行的代码出错时,也会继续向下执行。
注意:当使用./调用脚本时只会执行脚本当中的环境,而不会调用shell默认的./bash环境。(可以用来判断sh与bash环境的区别)

示例:
[ root@Lin Desktop]# cat 1.sh
#!/bin/bash		//bash环境
source 123
echo " 123"
[ root@Lin Desktop]# cat 11.sh
#!/bin/sh		//sh环境
source 123
echo " 123"
①./调用方式----./调用方式只会调用脚本当中的所写的环境
[ root@Lin Desktop]# ./1.sh
./1.sh: line 3: 123: No such file or directory		//bash:就算当运行的代码出错时,也会继续向下执行。
123
[ root@Lin Desktop]# ./ 11.sh
./11.sh: line 2 : " source: 123: file not found			//sh:当运行的代码出错时,不继续往下解释。
②bash调用方式(常用/更优化)----bash调用方式为不管文件当中写的是sh还是bash环境,都由bash环境来调用。(sh相当于不存在/是一个软链接,链接指向bash环境)
[ root@Lin Desktop]#echo $0
bash
[ root@Lin Desktop]# bash 1.sh
i.sh : line 3: 123: No such file or directory
123
[ root@Lin Desktop]# bash 11.sh
i1.sh: line 2: 123: No such file or directory
123

4、read命令

read命令: 
	-n x :可以读取x个字符,遇到回车/换行会提前终止
	-N x:可以读取x个字符,遇到回车/换行不会提前终止
	-p:输入提示词
示例:
[root@localhost ~]# read -p "xxx": USER
xxx:mq
[root@localhost ~]# echo $USER
mq

[root@localhost ~]# read -n 10
1234567890[root@localhost ~]# 
[root@localhost ~]# read -N 10	//回车、空格个算一个字符
1 3 5
 890[root@localhost ~]# 

5、其他

1、在Linux当中可执行文件的文件后缀都为.sh;在Windows当中为.bat/.cmd后缀。
2、#!表示调用一个shell环境(调用一个/bin/bash环境(也可以是/bin/sh))。
3、` :先执行`所包围的命令,再将结果放到外部命令执行一遍。
4、for循环与while循环区别:for循环是根据取值列表循环(函数括号中的内容);while循环根据的条件不同。