第四课.LinuxShell编程

什么是Shell

有人说Linux系统犹如核桃,有外壳和内核;
内核:kernal,Linus集中精力研究内核开发;
外壳:shell,是有命令行或者界面的应用程序;
狭义的shell指一种应用程序,提供了一个界面,用户通过这个应用才可以访问内核服务,广义的shell指一切应用程序,一般来说,linux学习应该先学shell,再学内核
shell脚本:shell script,是用shell编写的脚本程序,简称shell;
在学习windows时,会接触bat脚本,用于批处理,linux则需要学习shell
shell的意义
windows的理念是大而全,比如Visual Studio是个很好用的集成开发环境,但它实在体型巨大,这种大而全的理念适用于商业风格,不易做嵌入;
Linux是具备开源精神的,由于开源特性,它的程序也需要做到能适合不同需求的使用者,即要求应用程序便于组装,而shell脚本就是一个粘合剂,通过shell,可以将多个程序(命令)组装为一个大型项目
所谓shell,一般就是将命令组合,放到一个脚本内执行,shell也算是一种编程语言;
shell的开发流程:需求分析->建模->伪代码逻辑->代码实现;
当服务器上没有GUI时,可以通过sftp在本地写代码,同步到服务器执行,对于有GUI的服务器,可以直接在服务器上用visual studio code开发
Shell编程规则
Shell编程最好遵守一定的规范,变量和函数名小写,常量大写,函数内的变量加local

Shell编程

创建脚本

在命令行输入code打开vscode:

code

在vscode内创建hello.sh:
fig1
第一行为:

#!/bin/bash

这是向linux指明了,该文件要用bash解析,补充一下,在/etc/shells可以看到系统有哪些shell:
fig2
也可以查看默认的shell:

echo $SHELL

fig3
现在,我在hello.sh内键入echo "hello world\n",echo类似于标准输出,现在执行脚本不会对"\n"转义,要自动换行需要在echo后加参数-e,开启转义功能:

echo -e "hello world"

保存后,回到命令行,执行该文件,如果权限没有x(可执行),需要chmod改变权限,执行过程为:
fig4
注意,如果是在Windows下写的文件,到linux运行会遇到编码的差异,所以最好使用dos2unix达到编码转换的作用:

dos2unix ./filename.sh

注释

首先是单行注释:#,当然,行首用于解释,选择shell类型;
多行注释为:

:<<EOF
被注释的内容
EOF

fig5

Shell变量

shell变量命名只用英文,数字,下划线,同时不能使用shell的关键字;
变量分三种:局部变量,环境变量,特殊变量
局部变量
局部变量在当前shell中有效,在脚本或命令中定义,函数内的局部变量要加上local;
变量可以定义,使用,只读,删除:

a=baijingyi
b="baijingyi"

a和b的定义实质是一样的,加双引号""有推荐的意思,规范是最好加上双引号;
然后用echo输出:

echo "$a"
或者
echo $a
或者
echo ${a}

echo加不加双引号也没关系,在bash中,$开头表示变量,另外{…}用于变量替换:

echo ${var}abc

如果var值为1,则输出1abc
另外我可以定义只读变量:

#!/bin/bash
readonly name
name="baijingyi"
echo "${name}" 

执行脚本不会输出结果baijingyi,因为name是只读的,不允许赋值;
也可以删除变量:

unset name

环境变量
全局变量,所有程序都可以访问,建议大写;

env 查看当前的环境变量
export 导出环境变量
source 引入环境变量

现在脚本中新建变量,用export可以导出到环境变量中,但脚本结束后,该变量将被释放,所以需要用source使变量在当前会话中生效:

#!/bin/bash

#导出环境变量
export MY_NAME="baijingyi"
#查看
env | grep MY_NAME

假设文件名为hello.sh,执行使用:

source ./hello.sh

fig6
特殊变量
常见特殊变量如下:

echo $0 当前脚本文件名
echo $@ 输入脚本的所有参数
echo "$#" 参数的个数
echo "$$" 当前shell的进程ID 

基本运算

算术运算
加减乘除和取余:

#!/bin/bash
a=11
b=5

#运算, 使用关键字expr,注意不是单引号,是反斜撇
val=`expr $a + $b`
echo "$a+$b=$val"

#另一种运算写法
val=$[a-b]
echo "$a-$b=$val"

关系运算

-eq 相等
-ne 不相等
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于

比如:

#!/bin/bash
#关系运算
a=11
b=5

#例子,注意中括号需要空格
if [ $a -eq $b ]
then
    echo "$a -eq $b : a等于b"
else
     echo "$a -eq $b :a不等于b"
#fi为if语句的结束
fi

布尔与逻辑运算

! 非运算
&& 逻辑与
|| 逻辑或
== 相等
!= 不相等

比如:

#!/bin/bash
#布尔运算
a=11;b=5
#注意中括号需要空格
if [ $a -eq $b ]
then
	echo "a等于b"
else
	echo "a不等于b"
fi

#逻辑运算 注意有两个中括号
#注意中括号需要空格
if [[ $a -gt 0 && $b -gt 0 ]]
then
	echo "a,b大于0"
fi

文件测试运算

-d 是否为目录
-f 是否为普通文件
-r,-w,-x 是否可读可写可执行
-s 文件是否为空
-e 文件是否存在

实例:

#!/bin/bash

file=$0 #$0指当前脚本文件名
echo "文件是:$file"
#注意中括号需要空格
if [ -f $file ]
then
	echo "是普通文件"
fi

字符串,数组,分支循环,函数

字符串
字符串分两种,单引号和双引号;
单引号的字符串会原样输出,变量无效;双引号的字符串可以识别变量:

#!/bin/bash
course="Linux"
#单引号
seqence='学习$course'
echo seqence
#双引号
seqenceed="学习$course"
echo seqenceed

fig7
因此,如果要在字符串中引用变量,最好使用双引号;
字符串的三个常用技巧:

#!/bin/bash
#字符串长度
str="helloworld"
echo "字符串"$str"的长度为"${#str}

#获取子串,从第1个字符开始,取3个,即ell
echo "字符串"$str"的子串"${str:1:3}

#查找子串
matched=`expr index "$str" wo`
echo "字符串"$str"的wo子串位置为"$matched
#应该输出5

数组
数组下标从0开始,在shell内可以定义数组,修改数组,读数组,获取长度:

#!/bin/bash
#数组定义
arr=(aa bb cc "hello")

#修改元素
arr[2]="222"

#读数组
echo "读arr[2]"${arr[2]}
echo "所有元素"${arr[@]}

#获取数组长度
len=${#arr[@]}
echo "数组长度为"$len

fig8
分支
分支可以用if,elif,else,但这样的方式是顺序执行的分支,也可以用并行执行的开关case;
使用if else的分支:

#!/bin/bash
age=20
if [ $age -le 10 ]
then
	echo "少年"
elif [ $age -le 20 ]
then
	echo "青年"
else
	echo "其他"
#if的结束标志
fi

使用case的分支:

#!/bin/bash
status=1
case $status in
	0) echo "todo"
	;;
	1) echo "doing"
	;;
	2) echo "done"
	;;
esca

循环
循环一般常用for循环for...in...do...done

#!/bin/bash
arr=(aa bb cc)
for item in ${arr[@]}
do
	echo "$item"
done

循环遇到break时,代表跳出当前的循环;
函数
shell脚本支持函数定义和调用,为了提高程序复用效率:

#!/bin/bash
#函数定义
function myfunc()
{
	echo "这是一个shell函数"
}
#与python不同,shell的函数调用使用函数名
myfunc

fig9函数的参数传递和返回值:

#!/bin/bash

function madd()
{
	local ret=$[$1+$2]
	return $ret
}
madd 5 8
# $?是一个特殊变量:上一个指令的返回值 
echo $?

fig10

应用实例

猜数字

通过shell实现一个任务:
1.随机从0到99生成一个数字;
2.使用者手动输入数字;
3.程序判断,如果数字不同,告知是大了还是小了,使用者根据提示继续输入,直到数字正确,返回猜数字的次数,退出程序;

#!/bin/bash

#产生一个两位的随机数
answer=$(date +%s%N | cut -c16-17)
count=0
while :
do
	#记录判断次数
	count=$[count+1]
	echo -n "输入0到99之间的数字"
	#获取使用者的输入
	read aNum
	#如果相同,则退出
	if [ $aNum -eq $answer ]
	then
		echo "正确,一共猜了${count}次"
		break;
	#再比较,给出提示信息
	elif [ $aNum -lt $answer ]
	then
		echo "小于正确值"
	else
		echo "大于正确值"
	fi
done

获取CPU使用情况

#!/bin/bash

cat /proc/stat | grep "cpu"

探测本地网络

对一个局域网内的ip地址,探测是否畅通:

#!/bin/bash

function testping()
{
	local ip=$1
	#判断ip字符串的长度是否为0
	if [ -z "$ip" ]
	then
		echo "参数为空"
		return
	fi
	#ping的结果不要保存,放到/dev/null里相当于丢弃
	ping -c1 $ip &>/dev/null
	#ping的返回值为0代表正常
	if [ $? -eq 0 ]
	then
		echo "$ip on"
	else
		echo "$ip off"
	fi
}

for ((i=1; i<255; i++))
do
	# &符号比较特殊,代表函数调用是并发的
	testping "192.168.31.$i" &
done

#并发时需要wait
wait
echo "任务结束"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值