目录
2.2.1、shell介绍
2.2.1.1就是操作系统的终端命令行
(1)人机交互的接口,也是就是用户操作的命令行界面。
(2)如linux中的命令行就是一种shell, xx.sh 文件就是一个脚本文件,用于批量执行命令,shell的用途之一。
2.2.1.2 shell是一类编程语言
(1)不需要编译链接就可以解析运行的,只需要一个解析器就可以逐行的解析运行。
2.2.1.3、shell语言:sh、bash、csh、ksh、perl、python等都是脚本语言
(1)linux常用的是bash、sh;
(2)脚本语言一般在嵌入式中应用,主要是用来做配置。
(3)linux下最常用的脚本就是bash。
2.2.1.4、shell脚本的运行机制:解析运行
(1)shell是解析运行的,所谓解析运行,是shell解释器一行一行解析成二进制然后执行的(脚本语言本身不需要编译链接,其实真正执行的代码可能早就编译链接好了,我们只是根据shell来编写命令去逐个调用它而已)
2.2.2、手动写一个shell
(1)window 中换行是\r\n,linux中是\n,所以shell不能在window中直接编辑
(2)方法一:./xxx,运行,需要有可执行权限,
(3)方法二:source xxx.sh 不需要脚本可执行程序
(4)方法三:bash xx.sh
#!/bin/sh //指定shell执行时使用哪个解析器
echo "hello world"
(5)脚本使用#注释,多行的话每行都要加#
(6)shell 定义变量
shell是类型语言,所以shell没有类型
#定义变量 =号两边不能有空格
string="hello world"
echo $string
2.2.3、编程基础
(1)shell调用linux的命令
直接执行如: mkdir xxx
cd …
(2)反引号括起来执行(反引号是ESC下面波浪线的那个)
如:PWD=pwd
echo="$PWD"
(3)典型的if语句用法
if [表达式];then
xxx
else
xxx
fi
例子:判断文件是否存在
简写的if表达式
str=" "
[ -z $str ] || echo "nokong" #前面如果为真[ -z $str ](即判断是否为空,为空则真),则后面就不执行echo "nokong"
[ -z $str ] && echo "nokong" 与上面相反,如果为真[ -z $str ],则执行echo "nokong"
常用判断表达式
# 判断字符串是否为空
# str="df"
# if [ -z $str ];then
# echo "yes"
# else
# echo "no"
# fi
# 判断数字是否小于
# if [ 100 -lt 110 ];then
# echo "yes"
# else
# echo "no"
# fi
#判断数字是否相等
# if [ 111 -eq 110 ];then
# echo "yes"
# else
# echo "no"
# touch a.txt
# fi
#判断是否大于
# if [ 111 -gt 110 ];then
# echo "yes"
# else
# echo "no"
# touch a.txt
# fi
相关关键字解析
-d 判断目录是否存在
= 判断字符串是否相等
-eq 数字是否相等 equal
-gt 大于 greater than
-lt 小于 less than
-ge 大于等于 greanter or equal
-le 小于等于 less or equal
2.2.4、shell 循环结构
2.2.5.1、for 循环
#for循环
for i in `ls` #打印当前目录的文件
do
echo $i
done
#打印1~5的数字,打印的集合
for i in 1 2 3 4 5
do
echo $i
done
2.2.5.2、while循环
# #循环结构
# #while 循环结构
i=1
j=11
while [ $i -lt $j ]; do #i<j则进行循环
echo $i
i=$(($i + 1)) #相等于i++
done
2.2.5.3.echo创建和追加输入文件 追加到现有文件的末尾
# echo新创建a.c文件并追加“xxx”到文件a.c中,下面就是添加了一段代码
echo "
include<stdio.h>
int main(void)
{
return 0;
}
">a.c
# #echo在原有a.c文件中追加“xx”内容到输入文件a.c的文件末尾,添加是这个符号>+文件名 ,末尾追加是>>+文件名
echo "//我的程序">>a.c
2.2.6.1、case语句
var=3
case $var in #跟c语言最大的差别是没有break语句,shell默认内部集成有
1) echo "1" ;;
2) echo "2" ;;
3) ls ;; #var=3,执行这句语句
esac
2.2.6.2、调用shell程序传参给他
$# 表示传参的个数
#shell传参 $#只考虑真正的参数个数,与C不一样
echo $# $0 $1 $2 $3 $4
#$0 存储的是shell本身文件名,$#存储的是真正输入的参数个数(文件名不在里面,而c语言中文件名包含在内)
注:shell 关键字break与c语言意义相同(都是跳出循环体)但是用法不同, shell中case 语句不需要break的,break用在跳出循环体:如:while,下面是u-boot中shell部分片段:
#演示shift指令和$# $1 $#为传参的个数
echo $# $1
shift; #遇到这个语句后,输入的参数会左移,也就是把原来$1 =aa,移出去,$2=bb移进来,变成$1=bb
echo $# $1
#如传参两个 遇到shift 后,相等于把aa给左移出去只剩一个参数
./4.loop.sh aa bb
2 aa
1 bb
2.2.5、Makefile-u-boot
(1)Makefile 作用和意义:工程项目中c文件太多,管理不方便,因此用Makefile来做项目管理,方便编译链接过程。
解析:目标,依赖,命令
目标:最终生成的东西
依赖:生成目标的原材料
命令:加工方法
2.2.5.1、通配符%和Makefile自动化推导规则
所谓自动推导就是Makefile的规则,当Makefile需要某个目标时,它会把这个目标去套规则说明,一旦套上这个规则说明,则Makefile会执行这个规则用来依赖生成目标。也就是Makefile文件目标:之后的规则说明。 就有点像先用个宏观的规划(总目标),后面就是总目标(譬如最终生产出一辆汽车)给出了汽车需要的各个零部件,之后就要去生产这些零部件(也是后面需要完成的工作)。思路是:先总,后分。
Makefile定义使用变量和shell脚本中非常相似,都没有变量类型,直接使用。引用变量$(var)
伪目标(.PHONY)
如:clean :
伪目标没有依赖,执行伪目标就是为了执行目标下的命令。
可以用.PHONY声明这个是伪目标
Makefile 或者makefile都可以
Makefile中引用其他Makefile (include指令–引用的效果也是原地展开)
Makefile 注释:# xxx
命令前面用@用来静默执行
2.2.5.2、什么是静默执行
#演示Makefile用法
#没有依赖就直接执行下面语句 如果没有加@则先打印命令再执行语句如 先打印:“echo hello world” 再打印:"hello world"
#如果加了@则静默执行,就不打印命令语句直接显示执行结果 直接打印“hello world”
all:
@echo "hello world"
2.2.5.3、几个赋值运算符
(1)= 最简单的赋值
(2):= 一般的赋值 (比较安全点)
# 举例说明
A:=A
B:=$(A)BC
A:=DD
all:
echo $(B)
#如果没有“:”,B=$(A)BC,引用A的值是后面的DD,结果:DDAB
#如果有“:”,B:=$(A)BC,引用A的值是前面的A,结果:ABC
(3)?= 如果已经定义过则跳过本语句,否则赋值。
var="abc"
#如果var还没有赋值或定义过则赋值,否则跳过此语句
var ?="efgh"
all:
echo $(var)
(4)+= 接续赋值,把现在的值加到原来的值上,makefile的变量值可以看做是字符串
var=abc
var +=dddd
结果:abc dddd
环境变量
(1)export 导出的就是环境变量,环境变量名用大写,普通变量用小写。
(2)可以看做是整个工程中Makefile中共享的全局变量。不能随便使用,不然会影响到其他工程中Makefile的执行。
(3)Makefile中可能有些变量是Makefile中内部定义的内部环境变量或者是当前执行环境提供的换环境变量,譬如make传参给Makefile。
举例:
CC = GCC
all :
echo $(CC)
执行传参:make CC=gcc-linux-gcc 优先级最高的,传参覆盖掉内部CC变量
结果:echo gcc-linux-gcc
2.2.5.4、Makefile通配符
(1)* 若干个任意字符
(2)? 匹配1个任意字符
(3)[ ] 选择性匹配
(4)% 也是通配符,一般只用于规则描述中 如生成.o文件, %.o : %.c(需要.c文件生成.o文件)
#1.c 2.c 3.c text.c
all:
#匹配1.c 2.c 3.c text.c
#echo *.c
#匹配1.c 2.c 3.c
#echo ?.c
# 匹配1.c 、3.c
#echo [13].c
Makefile自动变量
(1)类型与c语言的宏定义
@
、
@ 、
@、< 、$^ 都是自动变量
$@ 规则的目标文件名
$^ 依赖的文件集合
all : 1.c 2.c 3.c
echo $@ # 打印 目标名字:all
echo $^ # 打印目标依赖文件:1.c 2.c 3.c
$< 规则的依赖文件名
all: 1.o 2.o 3.o text.o
%.o : %.c
echo $<
结果:
echo 1.c
1.c
echo 2.c
2.c
echo 3.c
3.c
echo text.c
text.c