今天来学习一下shell脚本,关于泰山派的build.sh
一、line7 - line17
err_handler() {
ret=$?
[ "$ret" -eq 0 ] && return
echo "ERROR: Running ${FUNCNAME[1]} failed!"
echo "ERROR: exit code $ret from line ${BASH_LINENO[0]}:"
echo " $BASH_COMMAND"
exit $ret
}
trap 'err_handler' ERR
set -eE
1、export
设置环境变量
2、unset
则是取消或者删除环境变量或者shell变量
3、err_handler
分析
$? 是获取上一个命令的状态,也就是unset RK_CFG_TOOLCHAIN
命令的返回值。
[ flag ] && return 0 || return 1
这个意思是,如果flag为true则运行&&后的命令,false则运行||后的命令。
所以连起来就是 unset RK_CFG_TOOLCHAIN
成功则退出err_handler,否则就会echo 一大堆错误
4、trap 'err_handler' ERR
用于捕捉shell运行过程中的ERR,当触发了ERR就会调用err_handler
。
以下是例子
#!/bin/bash
err_handler() {
echo "An error occurred. Exiting."
exit 1
}
# 设置 ERR 陷阱
trap 'err_handler' ERR
# 下面的命令如果出错,将会调用 err_handler 函数
false # 这个命令总是会失败,因此会触发 err_handler
echo "This line will not be printed."
上述代码在运行到false后就会调用err_handler,输出An error occurred. Exiting
set -e
执行脚本一旦出现非0的结果,则立马退出。E不清楚是什么,后面再看。
ok,继续。我们先跳过function部分,调用函数的时候再去分析。
二、line84 - line97 加载环境变量
CMD=`realpath $0`
COMMON_DIR=`dirname $CMD`
TOP_DIR=$(realpath $COMMON_DIR/../../..)
cd $TOP_DIR
BOARD_CONFIG=$TOP_DIR/device/rockchip/.BoardConfig.mk
TARGET_PRODUCT="$TOP_DIR/device/rockchip/.target_product"
TARGET_PRODUCT_DIR=$(realpath ${TARGET_PRODUCT})
if [ ! -L "$BOARD_CONFIG" -a "$1" != "lunch" ]; then
build_select_board
fi
unset_board_config_all
[ -L "$BOARD_CONFIG" ] && source $BOARD_CONFIG
变量赋值的部分就不说了。
realpath
令主要功能是解析给定的路径(相对路径、绝对路径、符号链接)并返回该路径的真实的绝对路径。这个命令可以解决符号链接(symlinks)、相对路径以及其它可能导致路径不明确的问题。
dirname
获取文件所在目录。
$0
是第一个参数,也就是脚本本身的名字。
cd $TOP_DIR
后,就到了存放build.sh脚本的目录下,也就是Release目录下。
在[]中,-a等同于与,-o等同于或||(但是在[[]]中,不能用-a -o,只能用&& ||)
-L filename 如果 filename为符号链接,则为真。
if [ ! -L "$BOARD_CONFIG" -a "$1" != "lunch" ]
为如果BOARD_CONFIG 不是一个符号链接 且 $1
不是lunch命令
则执行build_select_board
[ -L "$BOARD_CONFIG" ] && source $BOARD_CONFIG
为如果BOARD_CONFIG是软链接,则把这个文件中的内容添加到环境变量中
三、line1231 - line1239
if echo $@|grep -wqE "help|-h"; then
if [ -n "$2" -a "$(type -t usage$2)" == function ]; then
echo "###Current SDK Default [ $2 ] Build Command###"
eval usage$2
else
usage
fi
exit 0
fi
grep -wqE "help|-h"
grep搜索不用多说,
$@
:表示获取执行脚本传入的所有参数
-w
只匹配过滤的单词
-q
静默模式,不输出信息
-E
使用支持扩展的正则表达式元字符(就是支持 | 扩展匹配)
[ -n "$2" -a "$(type -t usage$2)" == function ]
-n "$2"
检查 $2
是否非空
type -t
获取函数/变量的类型
所以这里整个的意思就是查找输入参数是否带有help或者h字段。
如果有
则判断是不是需要输出usage$2
对应的某个帮助函数,或者输出整个帮助函数(usage)。
四、line1241 - line1244
OPTIONS="${@:-allsave}"
[ -f "device/rockchip/$RK_TARGET_PRODUCT/$RK_BOARD_PRE_BUILD_SCRIPT" ] \
&& source "device/rockchip/$RK_TARGET_PRODUCT/$RK_BOARD_PRE_BUILD_SCRIPT" # board hooks
${variable:-word}
如果变量variable已被设置且非空,则代入它的值。否则,代入word。
例如,如果有一个命令行工具mytool,它接受一些选项,如-a、-b和-c,那么可以使用这个变量来设置这些选项,例如:
OPTIONS=“${@:-a}” 如果用户没有指定任何选项,mytool将默认执行-a操作。
后面两句的意思:
如果device/rockchip/$RK_TARGET_PRODUCT/$RK_BOARD_PRE_BUILD_SCRIPT
文件存在,则source该文件。
看了下配置文件还原出来是这个device/rockchip/rk356x/app-build.sh
,但是我在目录中并没有找到,后面再看。
五、line1246 - line1300
这部分比较长。
for option in ${OPTIONS}; do
echo "processing option: $option"
case $option in
BoardConfig*.mk)
option=device/rockchip/$RK_TARGET_PRODUCT/$option
;&
*.mk)
CONF=$(realpath $option)
echo "switching to board: $CONF"
if [ ! -f $CONF ]; then
echo "not exist!"
exit 1
fi
ln -rsf $CONF $BOARD_CONFIG
;;
lunch) build_select_board ;;
all) build_all ;;
save) build_save ;;
allsave) build_allsave ;;
check) build_check ;;
cleanall) build_cleanall ;;
firmware) build_firmware ;;
updateimg) build_updateimg ;;
otapackage) build_otapackage ;;
sdpackage) build_sdcard_package ;;
toolchain) build_toolchain ;;
spl) build_spl ;;
uboot) build_uboot ;;
uefi) build_uefi ;;
loader) build_loader ;;
kernel) build_kernel ;;
modules) build_modules ;;
rootfs|buildroot|debian|yocto) build_rootfs $option ;;
pcba) build_pcba ;;
ramboot) build_ramboot ;;
recovery) build_recovery ;;
multi-npu_boot) build_multi-npu_boot ;;
info) build_info ;;
app/*|external/*) build_pkg $option ;;
createkeys) create_keys ;;
security_boot) security_is_enabled; build_ramboot; build_uboot boot ;;
security_uboot) security_is_enabled; build_uboot uboot ;;
security_recovery) security_is_enabled; build_recovery; build_uboot recovery ;;
security_check) check_security_condition ;;
security_rootfs)
security_is_enabled
build_rootfs
build_ramboot
build_uboot
echo "please update rootfs.img / boot.img"
;;
*) usage ;;
esac
done
今日有点疲乏,wait…
ok,继续
这段话是个遍历匹配没问题吧。遍历OPTIONS中所有的值并且用case去匹配。
比如遇到lunch)
就去 执行 build_select_board
。
重点是;&
, 表示并且匹配下个case。也就是说匹配完BoardConfig*.mk
后继续匹配*.mk
exit 1
一般表示异常退出
ln -rsf $CONF $BOARD_CONFIG
表示创建软链接,CONF为源文件,BOARD_CONFIG为软链接。
-r选项表示创建软链接时使用相对路径。
-s选项表示创建软链接而不是复制文件。
-f选项表示覆盖。
ok,build.sh主要的部分就是这些。后面再看具体的函数。