已开通新的博客,后续文字都会发到新博客
我们用几个问题来解释这篇文章要讨论的内容
为什么用\cd 而不用cd
在android原代码的提交中,我们发现了这个解释:
Use “\cd” to disable alias temporarily.
使用\cd 来临时屏蔽alias别名
具体作用如下示例:
function mycd()
{
echo "in mycd"
cd $@
}
alias cd='mycd'
function cproj()
{
pwd
\cd .. 或者 cd ..
pwd
}
cproj()
我们执行这个脚本,前者将会打印:
/home/foree/bin
/home/foree
后者将会打印:
/home/foree/bin
in mycd
/home/foree
android 如何定位TOP目录
循环递归,查找build/core/envsetup.mk这个路径下文件是否存在
function gettop
{
local TOPFILE=build/core/envsetup.mk
if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
# The following circumlocution ensures we remove symlinks from TOP.
(cd $TOP; PWD= /bin/pwd)
else
if [ -f $TOPFILE ] ; then
# The following circumlocution (repeated below as well) ensures
# that we record the true directory name and not one that is
# faked up with symlink names.
PWD= /bin/pwd
else
local HERE=$PWD
T=
while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
\cd ..
T=`PWD= /bin/pwd -P`
done
\cd $HERE
if [ -f "$T/$TOPFILE" ]; then
echo $T
fi
fi
fi
}
关于shell脚本中命令太长的多行写法
adb shell ps \
| tr -d '\r' \
| sed -e 1d -e 's/^[^ ]* *\([0-9]*\).* \([^ ]*\)$/\1 \2/'
如何进入到指定关键字的目录,并选择符合条件中的一个
function godir () {
if [[ -z "$1" ]]; then
echo "Usage: godir <regex>"
return
fi
T=$(gettop)
if [[ ! -f $T/filelist ]]; then
echo -n "Creating index..."
(\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > filelist)
echo " Done"
echo ""
fi
local lines
lines=($(\grep "$1" $T/filelist | sed -e 's/\/[^/]*$//' | sort | uniq))
if [[ ${#lines[@]} = 0 ]]; then
echo "Not found"
return
fi
local pathname
local choice
if [[ ${#lines[@]} > 1 ]]; then
while [[ -z "$pathname" ]]; do
local index=1
local line
for line in ${lines[@]}; do
printf "%6s %s\n" "[$index]" $line
index=$(($index + 1))
done
echo
echo -n "Select one: "
unset choice
read choice
if [[ $choice -gt ${#lines[@]} || $choice -lt 1 ]]; then
echo "Invalid choice"
continue
fi
pathname=${lines[$(($choice-1))]}
done
else
pathname=${lines[0]}
fi
\cd $T/$pathname
}
envsetup.sh的作用
export 一些函数,像如:
function lunch()
function _lunch()
function gettop
function getdriver()
function m()
function findmakefile()
function mm()
function mmm()
function mma()
function mmma()
function croot()
function cproj()
function pid()
以上这些就是咱们平时使用的croot,lunch,mm这些函数的来源,
然后在脚本的最后,需要判断一下当前环境的shell是否为bash,对于非bash来说,例如zsh,因为与bash的语法有微小差别,因此使用一些命令会出错,例如,lunch之后,如果直接选择数字,而不是类型,可能会导致lunch一个错误的机型
if [ "x$SHELL" != "x/bin/bash" ]; then
case `ps -o command -p $$` in
bash)
;;
*)
echo "WARNING: Only bash is supported, use of other shell would lead to erroneous results"
;;
esac
fi
然后最后,再查找device和vendor目录下vendorsetup.sh文件,目录层级最深为4层,我们可以以vendor_device-TAG的方式加入变量,通过add_lunch_combo加到Lunch的选择项中。
# Execute the contents of any vendorsetup.sh files we can find.
for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` \
`test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null`
do
echo "including $f"
. $f
done
我们来看看通过lunch启动都干了些什么(可以通过cat build/envsetup.sh|sed -n ‘/function lunch/,/^}/p’ 打印函数)
function lunch()
{
local answer
if [ "$1" ] ; then
answer=$1
else
print_lunch_menu
echo -n "Which would you like? [aosp_arm-eng] "
read answer
fi
local selection=
if [ -z "$answer" ]
then
selection=aosp_arm-eng
elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
then
if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
then
selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
fi
elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
then
selection=$answer
fi
if [ -z "$selection" ]
then
echo
echo "Invalid lunch combo: $answer"
return 1
fi
export TARGET_BUILD_APPS=
local product=$(echo -n $selection | sed -e "s/-.*$//")
check_product $product
if [ $? -ne 0 ]
then
echo
echo "** Don't have a product spec for: '$product'"
echo "** Do you have the right repo manifest?"
product=
fi
local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
check_variant $variant
if [ $? -ne 0 ]
then
echo
echo "** Invalid variant: '$variant'"
echo "** Must be one of ${VARIANT_CHOICES[@]}"
variant=
fi
if [ -z "$product" -o -z "$variant" ]
then
echo
return 1
fi
export TARGET_PRODUCT=$product
export TARGET_BUILD_VARIANT =$variant
export TARGET_BUILD_TYPE=release
echo
set_stuff_for_environment
printconfig
}
如上:主要关注点在于4个正则表达式
- elif (echo -n ")
- elif (echo -n KaTeX parse error: Double superscript at position 24: … grep -q -e "^[^̲\-][^\-]*-[^\-]…")
- local product=$(echo -n //")
- local variant=$(echo -n $selection | sed -e “s/[-]*-//”)
第一个是查找1-2位数的正则表达式
第二个是匹配vendor_product-eng这样格式的选择项
第三个用来提取-前边的关键字,例如meizu_m76-eng中的meizu_m76
第四个用来提取variant变量,就是eng,userdebug,user这几个变量
我们从这里可以看出,vendorsetup.sh中写出符合标准格式的combo,然后在lunch的时候导出
接下来我们进入lunch的世界