加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

通过阅读刷机脚本flash-all.sh来学习shell脚本

发布时间:2020-12-15 20:01:19 所属栏目:百科 来源:网络整理
导读:关于shell脚本的文章,教程很多。但是一般属于工具书类型的,遇到不清楚的再去查。 这里通过阅读Android的刷机脚本 flash-all.sh 来学习实际当中的shell是怎么写的。 flash-all.sh脚本 我选择的是HiKey版本的刷机文件,在Master分支的 device/linaro/hikey/i

关于shell脚本的文章,教程很多。但是一般属于工具书类型的,遇到不清楚的再去查。

这里通过阅读Android的刷机脚本flash-all.sh来学习实际当中的shell是怎么写的。

flash-all.sh脚本

我选择的是HiKey版本的刷机文件,在Master分支的device/linaro/hikey/installer目录下可以找到。

原始文件只有72行,所以这里加上我的注释都贴出来了

#!/bin/bash
# $# - 输入参数的个数
# -eq - 与=类似,都是判断两个操作对象是否相同,但是前者针对整数,后者是字符串和数字都适用
# 这个判断是:输入的参数个数是否为0,即有没有输入参数
if [ $# -eq 0 ]
  then
    echo "Provide the right /dev/ttyUSBX specific to recovery device"
    exit    # 退出shell
fi

# -e - 判断文件是否存在
# $1 - 第1个输入的参数
# 这个判断是:第1个参数指定的文件不存在
if [ ! -e "${1}" ]
  then
    echo "device: ${1} does not exist"
    exit
fi
DEVICE_PORT="${1}"
PTABLE=ptable-aosp-8g.img
# 如何输入的参数个数大于1,并且第2个参数为"4g",那么PTABLE变量为"ptable-aosp-4g.img"
if [ $# -gt 1 ]
  then
    if [ "${2}" == '4g' ]
      then
        PTABLE=ptable-aosp-4g.img
    fi
fi

# 返回当前shell脚本所在的路径
INSTALLER_DIR="`dirname ${0}`"
FIRMWARE_DIR="${INSTALLER_DIR}"

# for cases that not run "lunch hikey-userdebu"
# -z - 变量的长度是否为0,即是否定义了变量${ANDROID_BUILD_TOP}
# 如果没有定义,则以当前目录为基准进行变量赋值
if [ -z "${ANDROID_BUILD_TOP}" ]; then
    ANDROID_BUILD_TOP=${INSTALLER_DIR}/../../../../
    ANDROID_PRODUCT_OUT="${ANDROID_BUILD_TOP}/out/target/product/hikey"
fi

# 如果${DIST_DIR}没有赋值,那么赋值
if [ -z "${DIST_DIR}" ]; then
    DIST_DIR="${ANDROID_BUILD_TOP}"/out/dist
fi

#get out directory path
# 如果参数大于1个,那么遍历
# 从代码可以发现当前脚本支持2个参数:
# --out 值是自定义各个img的目录
# --use-compiled-binaries 如果有这个参数,表示使用编译生成的firmware
while [ $# -ne 0 ]; do
    case "${1}" in
        --out) OUT_IMGDIR=${2};shift;; # ";"表示连续命令,";;"表示本次循环结束,相当于高级语言中的continue
        --use-compiled-binaries) FIRMWARE_DIR="${DIST_DIR}";shift;;
    esac
    shift   # shift表示移除第1个参数,即原来的第3个参数变成第2个参数,以此类推
done    # 完成while循环

# 如果${FIRMWARE_DIR}是编译的目录,判断该目录下fip.bin与l-loader.bin是否存在
if [[ "${FIRMWARE_DIR}" == "${DIST_DIR}" && ! -e "${DIST_DIR}"/fip.bin && ! -e "${DIST_DIR}"/l-loader.bin ]]; then
    echo "No binaries found at ${DIST_DIR}. Please build the bootloader first"
    exit
fi

# 如果${OUT_IMGDIR}没有定义,那么使用${ANDROID_PRODUCT_OUT}作为其值
if [ -z "${OUT_IMGDIR}" ]; then
    if [ ! -z "${ANDROID_PRODUCT_OUT}" ]; then
        OUT_IMGDIR="${ANDROID_PRODUCT_OUT}"
    fi
fi

# 如果${OUT_IMGDIR}不存在
if [ ! -d "${OUT_IMGDIR}" ]; then
    echo "error in locating out directory,check if it exist"
    exit
fi

echo "android out dir:${OUT_IMGDIR}"

# 原本以为"烧写环境没有进行",但是看了代码才发现,这一步也进行了
# 可参考:http://wiki.lemaker.org/HiKey(LeMaker_version):Quick_Start
sudo python "${INSTALLER_DIR}"/hisi-idt.py --img1="${FIRMWARE_DIR}"/l-loader.bin -d "${DEVICE_PORT}"
# set a unique serial number --- 对serialno这个参数不熟悉,之前没见过
fastboot oem serialno
fastboot flash ptable "${INSTALLER_DIR}"/"${PTABLE}"
fastboot flash fastboot "${FIRMWARE_DIR}"/fip.bin
fastboot flash nvme "${INSTALLER_DIR}"/nvme.img
fastboot flash boot "${OUT_IMGDIR}"/boot.img
fastboot flash system "${OUT_IMGDIR}"/system.img
fastboot flash cache "${OUT_IMGDIR}"/cache.img
fastboot flash userdata "${OUT_IMGDIR}"/userdata.img

以上中文部分都是我的注释

从代码可以发现当前脚本支持2个参数:
–out, 值是自定义各个img的目录
–use-compiled-binaries 如果有这个参数,表示使用编译生成的firmware

脚本中用到的指令

$#
输入参数的个数

-eq与=的区别
两者都是用来判断两个操作对象是否相同,前者只适用于整数,而后者支持数字与字符串

-gt
大于

INSTALLER_DIR=”`dirname ${0}`”
计算表达式dirname ${0}的值,将其赋值给INSTALLER_DIR

-z与-n
-z是变量的字符串长度是否为0
-n是变量的字符串长度不为0

-d
目录是否存在

-e
文件是否存在

;与;;
;表示连续命令
;;表示本次循环结束,相当于高级语言中的continue

-ne
-eq相反,不等于

shift
常用于case中,表示移除第1个参数,即原来的第3个参数变成第2个参数,以此类推

有意思的if与case
这两个的语法比较有意思,结束标记是原来的字符串反过来写,即fiesac

这里列出来的语法非常有限,碰到不清楚的,大家可以自行查询

参考

  1. shell语法简介
  2. linux shell 判断变量是否为空。-n -z 有什么不同呢?
  3. Shell编程中Shift的用法
  4. shell 基础 $(cd dirname $0;pwd)
  5. linux中shell变量#,@, 0, 1,$2的含义解释
  6. Bash shell 中 “-eq” 与 “=” 等价吗?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读