您的位置:首页 > 运维架构 > Shell

安卓学习笔记--bash脚本

2014-08-26 15:52 288 查看
在linux系统下开发软件,常常感觉比较吃力的地方是看不懂各种脚本,因为脚本的语法实在是太诡异了,短短的几行脚本,写得像火星文,也许创造脚本的那些geeks智商太高,以为我们这些初入门者能看得懂他的火星文。

闲话少说,先记录一下一些简单的心得。

关于返回参数:

set -e 这一行的意思是,后面的脚本只要返回非零的值,就马上结束,后面的命令不再执行

$? 这么简化的符号是为了便于频繁的使用,这里代表上一个命令的返回值,如果是函数,就表示是函数return后面的值

脚本的输入类型有3种:

1. 用户输入

2. 前一个脚本的输出

3. 脚本的函数的参数

$n n为1--9的数,用户输入的参数。在bash脚本里,所有参数都是字符串类型,没有数字,小数这些

read, in , case , esac 这些都是linux命令,case 与 esac搭配使用,就像if 搭配 fi

`ls` 这个不是单引号,而是键盘!号左边的键,用这2个符号包住的是linux命令,然后它执行后返回的值就可以作为其他命令的输入。

$@ 这个符号代表所有传进来的参数,而且是已空格为区分

$* 代表所有参数,但不做区隔,是以整个字符串传进来

$# 表示传进来但参数的个数

$$ 当前命令所在的进程号 pid

bash脚本比较运算符

-n 操作数的长度不为零

-z 操作数的长度为零

-d 操作数对应一个目录 (意思是如果当前的路径存在这么一个目录,就返回1,否则返回0,通常用来检查当前路径是否正确)

-f 操作数对应一个文件

-eq 整数相等

= 判断字符串是否相等

!= 字符串不相等

分析一个具体的脚步文件,就是一个编译全志kernel的脚本,

#!/bin/bash       必须这样写,方便系统识别这个是bash格式的脚本                                                                                                                                                          
  2 
  3 set -e         如果执行的命令返回非0值,立刻中止,不再往下执行命令
  4 
  5 buildroot/scripts/mkcommon.sh $@      调用另外一个脚本,同时通过$@符号把用户传进来的参数变量传给mkcommon.sh这个脚本。通常我们调用这个脚本
是带了参数的,$./build.sh -p sun7i_android 这样,所以,等于说有2个参数传给下一个脚本。


然后我们继续看mkcommon.sh这个脚本:

#!/bin/bash
#
# scripts/mkcommon.sh
# (c) Copyright 2013
# Allwinner Technology Co., Ltd. <www.allwinnertech.com>
# James Deng <csjamesdeng@allwinnertech.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

BR_SCRIPTS_DIR=`dirname $0`   ---------获取当前的路径,因为我们执行这个脚本的位置是在lichee这个目录下面的,dirname是一个linux命令,$0就是脚本的名字,通常$1--9代表参数,那么$0代表命令或者脚本本身。也就是mkcommon.h这个脚本本身所在的路径。

if [ "$1" = "pack" ] ; then       ----如果传进来的第一个参数是pack的话
    ${BR_SCRIPTS_DIR}/build_pack.sh    ---跑去执行pack的脚本
    exit 0
fi

# source shflags
. ${BR_SCRIPTS_DIR}/shflags/shflags ----用一个点号,然后后面跟的通常也是一个脚本,是用来代替source这个命令的,就是把一些外部的变量或者模块导入进来

. ${BR_SCRIPTS_DIR}/mkcmd.sh     ----这个导入进来的是一些负责编译的函数

# define option, format:
#   'long option' 'default value' 'help message' 'short option'
DEFINE_string 'platform' 'sun7i' 'platform to build, e.g. sun7i' 'p'  ---这里定义可选的平台      
DEFINE_string 'board' '' 'board to build, e.g. evb' 'b'         ----定义可选的板
DEFINE_string 'module' '' 'module to build, e.g. buildroot, kernel, uboot, clean' 'm'  --定义编译的模组类型
DEFINE_boolean 'independent' false 'output build to independent directory' 'i'        ----不清楚

# parse the command-line
FLAGS "$@" || exit $?        ----检查命令行,就是传递进来的参数,FLAGS相信就在刚才source进来的函数
eval set -- "${FLAGS_ARGV}"   ----暂时看不懂

chip=${FLAGS_platform%%_*}      ---初始化这些变量
platform=${FLAGS_platform##*_}
board=${FLAGS_board}
module=${FLAGS_module}

if [ "${platform}" = "${chip}" ] ; then   ---为什么platform = chip就把platform设置为linux呢?
    platform="linux"
fi

if [ -z "${module}" ] ; then            ---大概是默认的意思吧,就是当用户没有设定这一项的时候就给它个默认值,-z就是长度为0的意思
    module="all"
fi

if ! init_chips ${chip} || \      ------看不太懂
   ! init_platforms ${chip} ${platform} ; then
    mk_error "invalid platform '${FLAGS_platform}'"
    exit 1
fi

if [ ${FLAGS_board} ] && \
   ! init_boards ${chip} ${platform} ${board} ; then
    mk_error "invalid board '${FLAGS_board}'"
    exit 1
fi

# init output directory
init_outdir       ----初始化输出的目录的函数,具体的实现在之前source进来的脚本

if [ ${module} = "all" ]; then   ---如果用户选择module的类型是all的话,就调用mklichee这个命令,也就是函数
    mklichee
elif [ ${module} = "boot" ] ; then
    mkboot
elif [ ${module} = "buildroot" ] ; then
    mkbr
elif [ ${module} = "kernel" ] ; then
    mkkernel
elif [ ${module} = "uboot" ] ; then
    mkuboot
elif [ ${module} = "clean" ] ; then
    mkclean
elif [ ${module} = "mrproer" ] ; then
    mkmrproer
elif [ ${module} = "distclean" ] ; then
    mkdistclean
else                   ------如果什么都不是,就报错
    mk_error "invalid module '${module}'"
    exit 1
fi

exit $?      ---退出并返回最后一个命令返回的值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: