嵌入式学习笔记-LINUX系统编程阶段-DAY01脚本
1.shell概述
1.1什么是shell?
前言:真正能够控制计算机硬件(CPU,内存,显示器)的,只有操作系统内核(kernel),图形化界面和命令指示假设在用户和硬件之间的一层桥梁。
由于安全、复杂、繁琐等原因,用户不能直接操作内核(不能也没必要),需要有一个桥梁,让用户通过这个桥梁,能够协调硬件资源。这个桥梁的作用就是链接用户与内核,接收到用户需求(命令等),简单处理过后传递给内核。这样的话,用户和内核之间多了一层类似于“代理”的东西,这层代理既保护了内核,又方便了用户。
如果用户直接操作计算机底层硬件资源,会造成不可逆转的错误,为了保护硬件资源,现在引入shell。
用户与硬件之间的关系:
1.2shell
shell既是应用程序,又是一种程序设计语言。
作为应用程序:shell是一个解析器
作为语言:shell是一种解释型语言,不需要编译,边解释边执行(批数据处理)
shell的功能:
1.自动化任务,可以完成一些重复性工作,例如定时清理日志,定时备份重要文档。
2.系统管理:可以协助用户管理系统系统资源。
3.软件安装与部署:根据shell脚本进行对应的配置,完成软件的自动化安装(后续会涉及到环境不同,环境配置也不同)
1.3shell的解析器版本
Linux中常用的shell解析器有三种:sh、ash、bash。在咱们常用的linux中,默认使用的解析器是:bash
1.4shell语言
shell是一种脚本语言,类似于C语言,我们只要按照相应的语法来进行相应的编辑,增加可执行权限,就可以在安装shell命令解释器的环境下执行。
1.5shell语言的种类
linux中的shell语言大致分为两类(进行环境配置)
1./etc/profile
针对linux下所有用户的配置(无论登录哪一个用户),用户第一次登录的时候,此配置执行
2.~/.bashrc
linux中每一个用户有一个对应的环境配置(登录用户不同,环境不同)
2.shell语法
2.1shell脚本文件
shell脚本文件是以.sh为后缀的
如果跨系统操作,例如在windows写的文件拖动到linux中,可能因为语法差异导致报错。(例如:linux中换行与windows可能不同)
解决方法:
2.2shell脚本语言的执行
方法1.chmod + x xxx.sh 然后./xxx.sh
方法2:bash xxx.sh 指定bash读取解析xxx.sh
方法3:. xxx.sh使用当前解析器读取解释xxx.sh
几种方法的区别:
1 ./与 bash执行过程基本一致:
a ./先去找#!/etc/ 指定的解析器,如果没有指定,选择默认解析器
b 后者指定用bash解析器运行,那么文件中的#!/etc/ 指定的解析器将不再起作用
c ./ 和bash都会另外开启一个解析器来解析(新开一个终端)
2 . 执行脚本不会开启新的shell,直接用当前的shell来解析
3.shell的变量
3.1定义变量
定义变量:变量=变量值
变量取值:$变量名注意:=两边不能有空格
清除变量:unset
读取变量:read
read num #读取变量
read str #读取字符串
只读变量:readonly
导出环境变量:(只导出当前终端,与其他无关)
先查看环境:终端输入 env
导出环境:export
可与理解为:
3.2双引号和单引号的区别
单引号:将单引号引起来的内容原封不动输出
双引号:可以将其中的变量解析
3.3系统预设变量(env中的)
3.4 $预设环境变量
$#:传给 shell 脚本参数的数量
$*:传给 shell 脚本参数的内容
$1、$2、$3、...、$9:运行脚本时传递给其的参数,用空格隔开
$?:命令执行后返回的状态
"$?"用于检查上一个命令执行是否正确(在 Linux 中,命令退出状态为 0 表示该命令正确执行,任何非 0 值表示命令出错)。
$0:当前执行的进程名
$$:当前进程的进程号
"$$"变量最常见的用途是用作临时文件的名字以保证临时文件不会重复
3.5脚本变量的特殊用法
- ``(数字1左边的)反引号,反引号中的内容作为系统命令,并且执行其内容,进行替换输出
- 转义字符 \ 等同于C语言中转义字符 \r \n \a等,但是需要加上 -e才能生效
- ()内的命令序列,只会影响()内的数据
- {}内的命令序列,会影响整个shell文件的数据
3.6条件测试语句
在写shell脚本时,经常遇到的问题就是判断字符串是否相等,可能还要检查文件状态或者进行一些数字测试,那么只有完成测试以后才能进行下一步动作
- test 命令可以完成 字符串、文件状态和数字测试
- 格式1:test condition
- 格式2: [ condition ] 注意,condition左右各有一个空格
3.6.1文本测试
判断条件:
-e 是否存在
-d 是目录
-f 是文件
-r 可读-w 可写
-x 可执行
-L 符号连接-c 是否字符设备
-b 是否块设备
-s 文件非空
3.6.2字符串测试
测试格式
格式1:
- test str_operator "str" (测试目标为1个)
- test "str1" str_operator "str2" (测试目标为2个)
格式2:
- [ str_operator "str" ](测试目标为1个)
- [ "str1" str_operator "str2" ](测试目标为2个)([ ]左边右边各有一个空格)
其中 str_operator 可以是:
= 两个字符串相等
!= 两个字符串不相等
-z 空串
-n 非空串
3.6.3数值测试
测试格式:
格式1
- test num1 num_operator num2
- [ num1 num_operator num2 ]
num_operator 可以是如下
3.6.4复合测试
4.控制语句
if case for while until break
4.1.if语句
4.1.1 if else语句
格式1:
if [ 条件 ];then #条件左右要加空格 语句1 #如果满足if后,执行此处
else语句2 #否则执行此处
fi #结束
代码案例:
代码案例:
输入一个文件名,判断是否存在,如果存在,展示内容,如果不存在,创建文件并且输入内容
#!/bin/bash
echo "请输入一个文件名"
read filename
if [ -e $filename ];thenif [ -d $filename -o -s $filename ];thenecho "为目录文件或文件为空"elsecat $filenamefi
elsetouch $filenameecho "hello file" >> $filenamecat $filename
fi
格式2:
if [ 条件1 ];then语句1
elif [ 语句2 ];then语句2
else语句3
if
4.2case
格式:
case $变量名称 in"值1")程序段一;;"值2")程序段二;;*) #其他情况其它程序段
exit 1 #退出
esac #结束 case倒过来写
代码案例:
#!/bin/bash
echo "请输入一个选择"
read str
case $str iny*|Y*) #输入y开头或者Y开头的选择都会匹配 通配符echo "用户输入确定";;"no")echo "用户选择退出";;*)echo "用户无操作"exti 1 #退出
esac
4.3for
格式1:
for((初始值;限制值;执行步阶)) # for((i=0;i<=10;i++))
do程序段;
done
案例:计算1+2+。。。+10
#!/bin/bash
declare -i i=0 #declare -i xx 将xx强制当成int类型数据来计算
declare -i data=10
declare -i sum=0
for((i;i<=data;i++))
do
sum=$sum+$i
done
echo "sum=$sum" #结果为55
格式2:
for var in con1 co2 con3 ...
do程序段
done
第一次循环时,$var 的内容为 con1
第二次循环时,$var 的内容为 con2
第三次循环时,$var 的内容为 con3
代码案例:
#!/bin/bash
declare -i i=0 #declare -i xx 将xx强制当成int类型数据来计算
declare -i data=10
declare -i sum=0
for var in 1 2 3 4 5 6 7 8 9 10
do
sum=$sum+$var
done
echo "sum=$sum" #结果为55
4.4while循环
格式:
while [ 条件 ]
do代码段
done
代码案例
#!/bin/bash
declare -i i=0 #declare -i xx 将xx强制当成int类型数据来计算
declare -i data=10
declare -i sum=0while [ $i -le 100 ]
dosum=$sum+$ii=$i+1
done
echo "sum=$sum" #结果为5050
4.5until
格式:
until [ 条件 ]
do代码段
done
#until用法与while恰好相反,until是condition成立时退出循环
代码案例:
#!/bin/bash
declare -i i=0 #declare -i xx 将xx强制当成int类型数据来计算
declare -i data=0
declare -i sum=0until [ $i -gt 100 ]
dosum=$sum+$ii=$i+1
done
echo "sum=$sum"
5.函数
可以解决脚本语言的重复性调用问题
格式1:
函数名(){
命令...
}
格式2:推荐
function 函数名(){ #shell脚本无需形参
命令...
}
5.1.当前源文件封装函数
案例:
#!/bin/bash
declare -i i=0 #declare -i xx 将xx强制当成int类型数据来计算
declare -i data=0
declare -i sum=0#函数定义
function my_add()
{sum=$1+$2return $sum
}#函数传参
my_add 10 20 #10会代替$1 20会代替$2#函数结果,上一行命令执行的结果
echo "结果是:$?" #结果是30
5.2函数分源文件(函数在别的文件)
需要导入
#!/bin/bash
source xxx #用source导入my_add函数所在的文件#函数传参
my_add 10 20#函数结果,上一行命令执行的结果
echo "结果是:$?"