最简单的shell
#!/bin/bash
echo "Hello World"
Shell 变量
注意: 变量的“=”前后不能有空格
#!/bin/bash
myStr="hello world"
myNum=100
访问变量
当想要访问变量的时候,需要使用$,否则输出的将是纯文本内容
#!/bin/bash
myStr="hello world"
myNum=100
echo $myStr
echo myNum
shell 运算
表达式
expr命令为Linux中的命令,一般用于整数值计算,但也可用于字符串操作。
- 格式
- expr argument operator argument
- 参数说明
- argument:为第一个参数
- operator:为操作运算符
- argument:为第二个参数
运算符号
运算符 | 含义 |
---|---|
+ | 加法运算 |
- | 减法运算 |
* | 乘法运算 |
/ | 除法运算 |
% | 求余 |
== | 相等 |
= | 赋值 |
!= | 不相等 |
-a | 与 |
-o | 或 |
! | 非 |
-eq | 两个数相等返回true |
-ne | 两个数不相等返回true |
-gt | 左侧数大于右侧数返回true |
-It | 左侧数小于右侧数返回true |
-ge | 左侧数大于等于右侧数返回true |
-le | 左侧数小于等于右侧数返回true |
= | 两个字符串相等返回true |
!= | 两个字符串不相等返回true |
-z | 字符串长度为0返回true |
-n | 字符串长度不为0返回true |
-d file | 检测文件是否是目录,如果是,则返回 true |
-r file | 检测文件是否可读,如果是,则返回 true |
-w file | 检测文件是否可写,如果是,则返回 true |
-x file | 检测文件是否可执行,如果是,则返回 true |
-s file | 检测文件是否为空(文件大小是否大于0,不为空返回 true |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true |
一些例子
#!/bin/sh
a=10
b=20
if [ $a -eq $b ]
then
echo "true"
else
echo "false"
fi
if [ $a -ne $b ]
then
echo "true"
else
echo "false"
fi
if [ $a -gt $b ]
then
echo "true"
else
echo "false"
fi
if [ $a -lt $b ]
then
echo "true"
else
echo "false"
fi
if [ $a -ge $b ]
then
echo "true"
else
echo "false"
fi
if [ $a -le $b ]
then
echo "true"
else
echo "false"
fi
获取字符串长度
mtext3="hello world"
echo ${#mtext3} #输出字符串长度
echo ${mtext3:1:4} #截取字符串 1到4
输出
11
ello
变量计算
a=3
b=5
val=`expr $a / $b`
echo "Total value : $val"
val=`expr $a % $b`
echo "Total value : $val"
if [ $a == $b ]
then
echo "a is equal to b"
fi
if [ $a != $b ]
then
echo "a is not equal to b"
fi
数组计算
#!/bin/sh
array=(1 2 3 4 5) #定义数组
array2=(aa bb cc dd ee) #定义数组
value=${array[3]} #找到某一个下标的数,然后赋值
echo $value #打印
value2=${array2[3]} #找到某一个下标的数,然后赋值
echo $value2 #打印
length=${#array[*]} #获取数组长度
echo $length
判断语句
- if
- if-else
- if-elseif
#!/bin/sh
a=10
b=20
if [ $a == $b ]
then
echo "true"
fi
if [ $a == $b ]
then
echo "true"
else
echo "false"
fi
if [ $a == $b ]
then
echo "a is equal to b"
elif [ $a -gt $b ]
then
echo "a is greater than b"
elif [ $a -lt $b ]
then
echo "a is less than b"
else
echo "None of the condition met"
fi
判断两个变量的值是否相等:test $[Val1] -eq $[Val]
if test $[a] -eq $[b]
then
echo "a 等于 b"
else
echo "a 不等于 b"
fi
for 循环
#!/bin/sh
for i in {1..5}
do
echo $i
done
for i in 5 6 7 8 9
do
echo $i
done
for FILE in $HOME/.bash*
do
echo $FILE
done
函数
没有返回值函数
#!/bin/sh
sysout(){
echo "hello world"
}
sysout
有返回值函数
test(){
aNum=3
anotherNum=5
return $(($aNum+$anotherNum))
}
test
result=$?
echo $result
定义传递参数的函数
#!/bin/sh
test(){
echo $1 #接收第一个参数
echo $2 #接收第二个参数
echo $3 #接收第三个参数
echo $# #接收到参数的个数
echo $* #接收到的所有参数
}
test aa bb cc
shell 颜色输出
利用echo 或者printf 可以输出带颜色的shell终端字体
例子
echo -e "\033[43;35m Hello World \033[0m \n"
printf "\033[44;36m Hello World \033[0m \n"
格式
echo -e "\003[背景颜色;文字颜色;显示方式m字符串\003[0m"
- -e 是命令 echo 的一个可选项,它用于激活特殊字符的解析器,可以转义反斜杠字符;
\033
引导非常规字符序列;- m 意味着设置属性然后结束非常规字符序列,显示的字符串之前有一个 m ;
显示方式具体内容:
显示方式 | 含义 |
---|---|
0 | 关闭所有属性 |
1 | 设置高亮 |
4 | 下划线 |
5 | 闪烁 |
7 | 反显 |
8 | 消隐 |
颜色
文字颜色 | 背景颜色 | 颜色 |
---|---|---|
30 | 40 | 黑色 |
31 | 41 | 红色 |
32 | 42 | 绿色 |
33 | 43 | 黄色 |
34 | 44 | 蓝色 |
35 | 45 | 紫红色 |
36 | 46 | 青蓝色 |
37 | 47 | 白色 |
Makefile
patsubst(替换通配符)
原型: $(patsubst 原模式, 目标模式, 文件列表)
或$(patsubst pattern, replacement,text)
功能:
查找<text>
中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>
,如果匹配的话,则以<replacement>
替换。这里,<pattern>
可以包括通配符“%”,表示任意长度的字串。如果<replacement>
中也包含“%”,那么,<replacement>
中的这个“%”将是<pattern>
中的那个“%”所代表的字串。(可以用“\”来转义,以“%”来表示真实含义的“%”字符)
返回:
**函数返回被替换过后的字符串。
**例子:
(patsubst %.c,%.o,x.c.c bar.c)
把字串“x.c.c bar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.o bar.o”
拓展-变量替换引用
对于一个已经定义的变量,可以使用“替换引用”将其值中的后缀字符(串)使用指定的字符(字符串)替换。格式为$(VAR:A=B)
(或者${VAR:A=B}
),意思是,替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。“结尾”的含义是空格之前(变量值多个字之间使用空格分开)。而对于变量其它部分的“A”字符不进行替换。例如:
foo := a.o b.o c.o
bar := $(foo:.o=.c)
在这个定义中,变量“bar”的值就为“a.c b.c c.c”。使用变量的替换引用将变量“foo”以空格分开的值中的所有的字的尾字符“o”替换为“c”,其他部分不变。如果在变量“foo”中如果存在“o.o”时,那么变量“bar”的值为“a.c b.c c.c o.c”而不是“a.c b.c c.c c.c”。
wildcard(扩展通配符)
原型: SRC = $(wildcard *.c ./foo/*.c)
功能:
搜索当前目录及./foo/下所有以.c结尾的文件,生成一个以空格间隔的文件名列表,并赋值给SRC.当前目录文件只有文件名,子目录下的文件名包含路径信息,比如./foor/bar.c。
notdir(去除路径)
原型: SRC = $(notdir wildcard)
功能:
去除所有的目录信息,SRC里的文件名列表将只有文件名。
addprefix(添加固定前缀)
原型: $(addprefix fixstring,string1 string2 ...)
功能:
其中,fixstring表示任意要添加的固定前缀,在逗号的后面可以是一个或多个要添加前缀的子字符串,多个子字符串之间用空格隔开,当然,你也可以用变量。
foreach
原型: $(foreach <var>,<list>,<text>)
功能:
这个函数的意思是,把参数<list>
;中的单词逐一取出放到参数<var>
;所指定的变量中,然后再执行< text>;所包含的表达式。每一次<text>
;会返回一个字符串,循环过程中,<text>
;的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>
;所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。
例子:
names := a b c d
files := $(foreach n,$(names),$(n).o)
上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。
注意,foreach中的;参数是一个临时的局部变量,foreach函数执行完后,参数;的变量将不在作用,其作用域只在foreach函数当中。
例子一
- makefile.md
#编译器管理
CC = gcc
RM = rm
MV = mv
AR = ar
PLATFORM = linux
ROOT_DIR = .
# 定义main 函数的名称
MAIN_FUNCTION ?= dsc_encode
BUILD_TIME = 2020
BUILD_TIME ?= $(shell date +%Y%m%d%H%M%S)
TARGET_NAME = $(TARGET_DIR)/$(MAIN_FUNCTION)
LIB_NAME = $(TARGET_DIR)/lib$(MAIN_FUNCTION)
#打印日志是否添加颜色
# LOG_COLOR_EANBLE = "Y"
#目录管理
TARGET_DIR=./target
OBJS=./objs
# 库文件路径
CCODE_DIRS = $(ROOT_DIR)/Huffman \
$(ROOT_DIR)/list_struct \
$(ROOT_DIR)/netfun \
$(ROOT_DIR)/toolC \
$(ROOT_DIR)/compress \
$(ROOT_DIR)/gcompress \
$(ROOT_DIR)/gzip \
$(ROOT_DIR)/mydiff \
$(ROOT_DIR)/crc
CCODE_INC += -I . -I include
# 非库文件
USER_DIRS =$(ROOT_DIR)/main
USER_INCS = .
# 入口函数文件
MAIN_FILE = $(ROOT_DIR)/main/$(MAIN_FUNCTION).c
HAL_DIRS = $(ROOT_DIR)/HAL/common \
$(ROOT_DIR)/HAL/$(PLATFORM)/socket \
$(ROOT_DIR)/HAL/$(PLATFORM)/thread
ifeq ($(LOG_COLOR_EANBLE),"Y")
CFLAGS +=-DLOG_COLOR_EANBLE
endif
CFLAGS += -Wall -Wno-format-extra-args -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Werror=implicit-int -Werror=enum-compare -Werror=return-type -Werror=parentheses\
-Wno-implicit-function-declaration -Wformat=0 -Wno-comment -Werror \
-Wno-unused-variable -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-unused-function -Wno-unused-value
CFLAGS += -lrt -g -L/usr/lib64/ -lpthread -lm
CFLAGS += -fPIC
CFLAGS += -O0 -DBUILD_TIME=\"$(BUILD_TIME)\"
CFLAGS += -D$(MAIN_FUNCTION)_main=main
- makefile
include makefile.mk
# 平台宏变量 -- 开始
HAL_INC_DIR = $(patsubst %,-I %,$(HAL_DIRS))
HAL_INC_DIR += $(HAL_INC)
HAL_SRC_FILES = $(foreach N, $(HAL_DIRS),$(wildcard $(N)/*.c)) #获取所有.c文件
HAL_COMPILE_FILES = $(addprefix $(OBJS)/,$(HAL_SRC_FILES:.c=.o) ) #加上输出目录
# 库宏变量 -- 结束
# 库宏变量 -- 开始
CCODE_UNIT_INC_DIR = $(patsubst %,-I %,$(CCODE_DIRS))
CCODE_UNIT_INC_DIR += $(CCODE_INC)
CCODE_UNIT_SRC_FILES = $(foreach N, $(CCODE_DIRS),$(wildcard $(N)/*.c)) #获取所有.c文件
CCODE_COMPILE_FILES = $(addprefix $(OBJS)/,$(CCODE_UNIT_SRC_FILES:.c=.o) ) #加上输出目录
# 库宏变量 -- 结束
# 用户变量 -- 开始
USER_INC_DIR = $(patsubst %,-I %,$(USER_DIRS))
USER_INC_DIR +=$(USER_INCS)
USER_SRC_FILES = $(foreach N, $(USER_DIRS),$(wildcard $(N)/*.c)) #获取所有.c文件
USER_COMPILE_FILES = $(addprefix $(OBJS)/,$(USER_SRC_FILES:.c=.o) ) #加上输出目录
# 用户变量 -- 结束
target:CREATE_PATH
@echo "ccode Files :" $(CCODE_DIRS)
@echo "user Files :" $(USER_DIRS)
@echo "CCODE_UNIT_INC_DIR :" $(CCODE_UNIT_INC_DIR)
@echo "CCODE_UNIT_SRC_FILES :" $(CCODE_UNIT_SRC_FILES)
@echo "CCODE_COMPILE_FILES :"$(CCODE_COMPILE_FILES)
@echo "HAL_INC_DIR :" $(HAL_INC_DIR)
@echo "HAL_SRC_FILES :" $(HAL_SRC_FILES)
@echo "HAL_COMPILE_FILES :" $(HAL_COMPILE_FILES)
@make $(TARGET_NAME).bin
@make $(LIB_NAME).so
@echo "========================================== success =========================================="
@ls -lh $(TARGET_NAME).bin
@ls -lh $(LIB_NAME)*
@echo "============================================================================================="
CREATE_PATH:
@echo "mkdir project dir " $(TARGET_DIR) $(OBJS)
@mkdir -p $(TARGET_DIR)
@mkdir -p $(OBJS)
@mkdir -p $(patsubst %,$(OBJS)/%,$(CCODE_DIRS) $(USER_DIRS) $(HAL_DIRS) )
$(TARGET_NAME).bin:$(HAL_COMPILE_FILES) $(USER_COMPILE_FILES) $(LIB_NAME).a
$(CC) -o $@ $^ $(CFLAGS)
$(LIB_NAME).a:$(CCODE_COMPILE_FILES)
$(AR) rcf $@ $^
$(LIB_NAME).so:$(CCODE_COMPILE_FILES)
$(CC) -shared -o $@ $^
#编译.o文件
$(OBJS)/%.o: %.c
@echo "src:" $<
@echo "src obj:" $@
$(CC) -c $< -o $@ $(CFLAGS) $(CCODE_UNIT_INC_DIR) $(USER_INC_DIR) $(HAL_INC_DIR)
clean:
$(RM) -rf $(OBJS) $(TARGET_DIR)