Shell 脚本(shell script),是一种为 shell 编写的脚本程序。Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,常见的有:

  1. Bourne Shell(/usr/bin/sh或/bin/sh)
  2. Bourne Again Shell(/bin/bash)

bash是大多数Linux 系统默认的 Shell,在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以像 #!/bin/sh同样也可以改为 #!/bin/bash

#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序

Shell参数学习
unset
为shell内建指令,可删除变量或函数

shell 中 [-eq] [-ne] [-gt] [-lt] [ge] [le]
-eq	//等于
-ne	//不等于
-gt //大于greater
-lt //小于less
-ge //大于等于
-le //小于等于

Shell 中 [$0] [$n] [$#] [$*] [$@] [$?] [$$]
$0 //当前脚本文件名
$n //传递给脚本或函数的参数,n为数字,表示第几个参数,例:$1为第一个参数,$2为第二个参数
$# //传递给脚本或函数的参数个数
$* $@ //传递给脚本或函数的所有参数
区别:当不被双引号""包含时,都以分开形式输出所有参数,如:$1""$2""$3"
当不被双引号包含时,$*将所有参数作为整体输出,如:"$1 $2 $3",$@还是以分开形式输出
$? //上个命令的退出状态或函数的返回值
$$ //当前Shell进程ID


if [ -e TEMP_AP_VERSION ]; then
	TEMP_AP_VERSION=$(cat TEMP_AP_VERSION)
else
	TEMP_AP_VERSION=""
fi
-e filename //如果 filename存在,则为真
-d filename //如果 filename为目录,则为真 
-f filename //如果 filename为常规文件,则为真
-L filename //如果 filename为符号链接,则为真
-r filename //如果 filename可读,则为真 
-w filename //如果 filename可写,则为真 
-x filename //如果 filename可执行,则为真
-s filename //如果文件长度不为0,则为真
-h filename //如果文件是软链接,则为真


if [ $? -eq 0 ]; then
	echo "build success" 
else
	echo "build fail"
fi
用于判断上条命令是否执行成功 0为成功


[shell] while read line do done < file
read通过输入重定向,把file的第一行所有的内容赋值给变量line,
循环体内的命令一般包含对变量line的处理;然后循环处理file的第二行、第三行直到file的最后一行。

""x = ${myversion}x
如果写成["$1" = "$2" ] 在 $1,$2为空时会在某些bash版本中出现编译错误,所以运用了shell中的字符抵消原则

rm -f !(checksparse.py)
除了checksparse.py都删除


2>&1
表示把标准错误输出 重定向到 标准输出,输出到一个文件

输出重定向
Command > filename	把标准输出重定向到一个新文件中
Command >> filename	把标准输出重定向到一个文件(追加)
输入重定向
Command < filename	 Command 命令以 filename 文件作为标准输入
Command << delimiter 从标准输入中读入,以delimiter为结束符。这就是Bash的HereDoc用法


unzip
Linux用于解压缩zip文件命令
https://www.runoob.com/linux/linux-comm-unzip.html
-o   		//不必先询问用户,unzip执行后覆盖原有文件
-d<目录>	   //指定文件解压缩后所要存储的目录。
Shell退出状态码
06-09 10:36:02.415     0     0 I init    : processing action (persist.odm.gpio_test=1) from (/vendor/etc/init/hw/init.target.rc:472)
06-09 10:36:02.418     0     0 I init    : starting service 'meig_gpio_test'...
06-09 10:36:02.477     0     0 I init    : Service 'meig_gpio_test' (pid 6933) exited with status 127

0 命令成功结束
1 通用未知错误
2 误用shell命令
126 命令不可执行
127 没找到命令
128 无效退出参数
128+x Linux 信号x的严重错误
130 Linux 信号2 的严重错误,即命令通过SIGINT(Ctrl+C)终止
255 退出状态码越界

参考:

文件描述符 File Discription

名称

代码

操作符

Java中表示

Linux 下文件描述符(Debian 为例)

标准输入(stdin)

0

< 或 <<

System.in

/dev/stdin -> /proc/self/fd/0 -> /dev/pts/0

标准输出(stdout)

1

>, >>, 1> 或 1>>

System.out

/dev/stdout -> /proc/self/fd/1 -> /dev/pts/0

标准错误输出(stderr)

2

2> 或 2>>

System.err

/dev/stderr -> /proc/self/fd/2 -> /dev/pts/0

参考:https://yanbin.blog/linux-input-output-redirection/

Shell脚本示例
#!/bin/bash
echo -e "\n"

unset DEBUGARR
DEBUGARR[1]="user"
DEBUGARR[2]="userdebug"

unset MDBRANCH
MDBRANCH[1]="trinket"
MDBRANCH[2]="trinket_Gms"

if [ $# -lt 2 ]
then
    echo "usage: $0 [${DEBUGARR[1]}|${DEBUGARR[2]}] [${MDBRANCH[1]}|${MDBRANCH[2]}]"
    echo -e "\n\n"
    exit -1
fi
if echo "${DEBUGARR[@]}" | grep -w "${1}" &>/dev/null; then
    echo "BUILD_TYPE:${1}"
else
    echo "BUILD_TYPE:${1} error" 
    exit -1
fi

if echo "${MDBRANCH[@]}" | grep -w "${2}" &>/dev/null; then
    echo "MDBRANCH:${2}"
else
    echo "MDBRANCH:${2} error" 
    exit -1
fi

echo -e "\n\n"
echo "##################### START TO GET MODEM BIN ####################"
scp build@192.168.0.181:/home5/build/qcm6125-la-1-0_amss_standard_oem/modem.zip ./
unzip modem.zip -d ./modem
echo "##################### END GET MODEM BIN ####################"

echo -e "\n\n\n"
echo "##################### START TO UPDATE ANDROID CODE ####################"
# git checkout SLM920_custom
# rm out/ -rf
# git pull
echo "##################### END UPDATE ANDROID CODE ####################"

echo -e "\n\n\n"
echo "##################### INIT ENVIRONMENT VARIABLES ####################"
echo "V01" >  INTERN_VERSION
if [ "$1" = "userdebug" ] ; then
    echo "T12" > TEMP_AP_VERSION
else    
    echo "U12" > TEMP_AP_VERSION
fi

if [ "$2" = "trinket" ] ; then
    echo "SLM920" > PROJECT_NAME
else    
    echo "SLM920Gms" > PROJECT_NAME
fi

project=$2
echo "##################### END ENVIRONMENT VARIABLES ####################"

echo -e "\n\n\n"
echo "##################### START TO COMPILE ANDROID CODE ####################"
source build/envsetup.sh
lunch ${project}-$1
make  update-api -j16
bash build.sh dist -j16 2>&1|tee 1.log
if [ ! $? -eq 0 ]; then
    echo "make error"
    exit -1
fi
echo "##################### END TO COMPILE ANDROID CODE ####################"

echo -e "\n\n\n"
echo "##################### START TO COMPRESS SOFTWARE IMAGE ####################"
rm tmp -r
mkdir tmp  
cp -rf modem/out/* tmp
rm sparseimage/rawprogram*.xml
cp modem/out/rawprogram*.xml  sparseimage
./meig_sparseimage.sh ${project}

cp modem/out/rawprogram*.xml  tmp
cp sparseimage/super_*.img tmp
cp sparseimage/metadata_*.img tmp
cp sparseimage/userdata_*.img tmp
cp sparseimage/*split.xml tmp

cp out/target/product/${project}/odmconfig_gpiotest.mbn tmp
cp out/target/product/${project}/abl.elf tmp
cp out/target/product/${project}/boot.img tmp
cp out/target/product/${project}/cache.img tmp
cp out/target/product/${project}/emmc_appsboot.mbn tmp
cp out/target/product/${project}/persist.img tmp
cp out/target/product/${project}/ramdisk.img tmp
cp out/target/product/${project}/ramdisk-recovery.img tmp
cp out/target/product/${project}/recovery.img tmp
cp out/target/product/${project}/userdata.img tmp/
cp out/target/product/${project}/userdata_16G.img tmp
cp out/target/product/${project}/userdata_32G.img tmp
cp out/target/product/${project}/persist.img tmp
cp out/target/product/${project}/mdtp.img tmp
cp out/target/product/${project}/obj/KERNEL_OBJ/vmlinux tmp
cp out/target/product/${project}/splash.img tmp
cp out/target/product/${project}/dtbo.img tmp
cp out/target/product/${project}/vbmeta.img tmp
cp out/target/product/${project}/vbmeta_system.img tmp
cp out/target/product/${project}/metadata.img tmp

echo $MEIG_AP_VERSION > tmp/AP_VERSION
function packagefiles()
{
    newpath=${1}
    rm ${newpath} -rf
	mkdir ${newpath}_symbol
	mv tmp/SymbolTable ${newpath}_symbol
	mv tmp/vmlinux ${newpath}_symbol
    mv tmp ${newpath} 
    zip -r ${newpath}.zip ${newpath}
    zip -r ${newpath}_symbol.zip ${newpath}_symbol
    cp out/dist/*-ota.zip ./${newpath}_ota.zip
    cp out/dist/merged-qssi_${project}-target_files.zip ./${newpath}_target_files.zip
} 
rm software_version.txt
python software_version.py
while read myversion
do 
    if [ ! ""x = ${myversion}x ]
    then
        echo "Version:"$myversion
        packagefiles $myversion
    fi
done < software_version.txt
echo "##################### END  TO COMPRESS SOFTWARE IMAGE ####################"