Bash 기술: 안 드 로 이 드 플랫폼 의 개발 효율 을 대폭 향상 시 키 는 Shell 스 크 립 트

17009 단어 linuxbashshell
이전 글 은 임의의 최상 위 디 렉 터 리 를 지정 할 수 있 는 quickcd.sh 스 크 립 트 를 소개 했다. 최상 위 디 렉 터 리 아래 에서 특정 디 렉 터 리 로 빠르게 cd 이동 할 수 있다.
quickcd.sh 스 크 립 트 는 일반적인 것 으로 각종 디 렉 터 리 구조 에 적용 된다.
안 드 로 이 드 개발 에 종사 하려 면 안 드 로 이 드 소스 디 렉 터 리 사이 에서 자주 전환 해 야 한다.
또한 스 크 립 트 를 수정 하여 Android 와 관련 된 기능 을 지원 할 수 있 습 니 다.
예 를 들 어 하나의 옵션 을 지정 하면 자동 source, lunch, 모든 안 드 로 이 드 소스 코드 를 컴 파일 할 수 있 습 니 다.
특정한 디 렉 터 리 에 들 어 갈 때 이 디 렉 터 리 의 코드 를 자동 으로 컴 파일 합 니 다.잠깐 만.
이 글 은 androidcd.sh 스 크 립 트 를 소개 합 니 다. quickcd.sh 스 크 립 트 를 바탕 으로 안 드 로 이 드 와 관련 된 코드 와 옵션 을 추가 합 니 다.
실제로 androidcd.sh 스 크 립 트 지원 quickcd.sh 의 모든 기능 은 임의의 최상 위 디 렉 터 리 에 도 사용 할 수 있 습 니 다.
스 크 립 트 코드 에 안 드 로 이 드 관련 코드 와 옵션 이 더 들 어 있 을 뿐 입 니 다.
이 옵션 이 필요 하지 않 으 면 이전 글 에서 소개 한 quickcd.sh 스 크 립 트 를 사용 하면 됩 니 다. 이 코드 는 비교적 독립 적 입 니 다.
구체 적 인 스 크 립 트 코드, 참고 프로필 내용, 그리고 테스트 예 를 제공 합 니 다.
스 크 립 트 코드androidcd.sh 스 크 립 트 의 구체 적 인 코드 는 다음 과 같 습 니 다.
이 코드 에 서 는 대부분의 핵심 코드 에 대해 상세 한 설명 을 제공 하여 읽 기 에 편리 하 다.
이 글 의 뒤에 도 간단 한 테스트 예 를 제공 하여 참고 할 수 있다.
#!/bin/bash
#                              cd.
#                    ,             ,  
#          cd       .        :     |    
#      "b|frameworks/base",  b      , frameworks/base     
#   .                ,      source androidcd.sh b
#       cd   framework/base    ,               cd.
#           ,     cd     ,    source      
#     .     ~/.bashrc                 :
#   alias c='source androidcd.sh'
#      c   ,       source androidcd.sh   .
#      androidcd.sh      PATH         .   /usr/bin   .
#    androidcd.sh               ,          .

#                 .          、       .
#    dirinfo.txt          ,   HOME     .liconfig    .
DEFAULT_DIRINFO="${HOME}/.liconfig/dirinfo.txt"

# PARSECFG_filepath   parsecfg.sh        .         ,
#             ,                .     
# androidcd.sh     parsecfg.sh        source      .  
# source    ,       shell              .    
# PARSECFG_filepath       source parsecfg.sh,          .
if [ -z "$PARSECFG_filepath" ]; then
    #            ,                 .
    source parsecfg.sh
    #    parsecfg.sh     open_config_file()         .
    open_config_file "$DEFAULT_DIRINFO"
    #   parsecfg.sh            ,   ,      .
    if [ $? -ne 0 ]; then
        return 1
    fi
fi

#                 ,             
#         ,           .         
#           .                .
#            "default",              .
open_user_config_file()
{
    if [ $# -ne 1 ]; then
        echo "Usage: $FUNCNAME filepath"
        return 1
    fi

    local filepath
    if [ "$1" == "default" ]; then
        filepath="$DEFAULT_DIRINFO"
    else
        filepath="$1"
    fi

    #    parsecfg.sh   open_config_file         
    open_config_file "$filepath"
    #   return        ,             .
    return
}

#     DIRECTCD_TOP_DIR                .
#          code/  ,     cd               code/.
#                    (       )       cd.
#   ,          ,               ,       
#              .       ,         ,    cd.
# NOTE:                .   cd  ,        .   
#      cd           .         ,          .
# DIRECTCD_TOP_DIR=""

#            '+' ,                   .
COMPILE_PREFIX="+"
#      Android      lunch     .         project  .
#       ,    DEFAULT_LAUNCH_COMBO        project   .
DEFAULT_LAUNCH_COMBO="K80129AA1-userdebug"

quickcd_show_help()
{
printf "USAGE
    source androidcd.sh [option] [symbol]
OPTIONS
    option:        ,    :
        -h:         .
        -f:            .        ,         .
                     'default',              .
        -p:                      .
        -s:    cd        .        ,         .
        -r:            .
        -l:                   .
        -v:                   .
        -i:             .               .
        -e:    vim          ,    .
        -a:                       .        ,
                   ,          .    :     |  
              : -a 'b|frameworks/base'.   b       ,   
                 .       ,    b             .
        -d:                       .      
              ,      .                    .
               -d b,          b   .
        -g:  Android          .            .
        -n:   source lunch   ,     .        project  .
               project     lunch        .
                     'dl',            project.
        -m:  Android           .            project.
               project     lunch        .
                     'dl',            project.
    symbol:     ,    cd       .        -l -v     .
                       '+',                   .

                       ,     cd       .
NOTE
         alias c='source androidcd.sh'    c        .
"
}

#                 .
show_top_dir()
{
    echo "            : ${DIRECTCD_TOP_DIR}"
    echo "          : ${PARSECFG_filepath}"
}

#            .                 .
#                ,      .
setup_top_dir()
{
    if [ $# -ne 1 ]; then
        echo "Usage: $FUNCNAME top_dir"
        return 1
    fi

    #               ,    cd         .
    \cd "$1"
    if [ $? -eq 0 ]; then
        #               .             
        #     ,            ,         .
        DIRECTCD_TOP_DIR="$(pwd)"
    else
        echo "  :            .           ."
        return 2
    fi
}

#    DIRECTCD_TOP_DIR      .          .
#            source     .         , 
#    shell  ,DIRECTCD_TOP_DIR        .        ,
#                    ,        ,    .
#    -r        reset_top_dir()              .
#       PARSECFG_filepath      ,          .
reset_top_dir()
{
    DIRECTCD_TOP_DIR=""
    PARSECFG_filepath=""
}

#                ,        ,          .
#   ,      code/dev/.       shell      code/test/,
#             cd   code/test/        ,     cd
#   code/dev/        ,                 .
#         ,            ,    .
check_top_dir()
{
    #   man bash "Compound Commands"    , =~            
    #      .               ,       0,    1.
    if [[ ! $(pwd) =~ "${DIRECTCD_TOP_DIR}" ]]; then
        #                    ,            .
        echo -e     '\e[31m' $(pwd) '\e[0m'           .
        echo -e          '\e[32m' ${DIRECTCD_TOP_DIR} '\e[0m'     !
    fi
}

#   Android       source、lunch   .            
#   project   .   project   lunch       .       
#   "dl",           project,  DEFAULT_LAUNCH_COMBO     .
source_and_lunch()
{
    #    DIRECTCD_TOP_DIR     ,          ,    
    if [ -z "${DIRECTCD_TOP_DIR}" ]; then
        echo "  :          ,    -h           ."
        return 2
    fi

    if [ $# -ne 1 ]; then
        echo "Usage: $FUNCNAME launch_combo"
        return 1
    fi

    local lunch_combo
    if [ "$1" == "dl" ]; then
        # "dl"              project
        lunch_combo="${DEFAULT_LAUNCH_COMBO}"
    else
        lunch_combo="$1"
    fi

    \cd "${DIRECTCD_TOP_DIR}"
    source build/envsetup.sh
    #  Android "build/envsetup.sh"   ,   print_lunch_menu()    
    #     lunch  ,     "1. aosp_arm-eng".  ,1  lunch    ,
    # "aosp_arm-eng" lunch   . lunch      lunch     lunch 
    #        lunch   .   grep       ,  awk     
    #  ,           lunch   ,    lunch     .
    lunch $(print_lunch_menu | grep "$lunch_combo" | awk '{print $2}')
    return
}

#    Android           .               project.
#       , compile_android       source_and_lunch   ,   
#           -s       source_and_lunch       .   
#       source、lunch , compile_android     lunch.     
# Android            lunch     .     envsetup.sh    
#         ,            ,          ,    .
compile_android()
{
    if [ $# -ne 1 ]; then
        echo "Usage $FUNCNAME android_lunch_combo"
        return 1
    fi

    source_and_lunch "${1}" && \
        make -j16 2>&1 | tee build_android.log
    if [ $? -ne 0 ]; then
        echo -e '\e[31m   Android   !\e[0m'
        return 1
    fi
}

#   Android                     ,      
#            ,           cd          .  
#        ,          ,      cd   .
#        Android   build/make/envsetup.sh  ,       .
godir() {
    #    DIRECTCD_TOP_DIR     ,          ,    
    if [ -z "${DIRECTCD_TOP_DIR}" ]; then
        echo "         ,   -h          ."
        return 1
    fi
    if [[ -z "$1" ]]; then
        echo "Usage: godir "
        return 1
    fi
    local T="${DIRECTCD_TOP_DIR}/"
    # envsetup.sh          filelists   ,        
    #   gtags.files,   gtags        ,          
    #     ,         .
    local FILELIST="gtags.files"
    if [[ ! -f $T/${FILELIST} ]]; then
        echo -n "Creating index..."
        \cd $T
        #    find     bionic、build、frameworks       ,
        #    -path -prune            test、git     
        #    ,                   .  $    
        #    .     -print       ,            
        #  ,    -prune   ,    -prune   ,    -regex
        #        . -regex   -type      -o,       .
        find ./bionic ./build ./device ./external \
            ./frameworks ./hardware ./kernel \
            ./packages ./system ./vendor \
            \( -path "*test*" -o -path "*tools" -o -path "*docs" \
            -o -path "*git*" -o -path "*svn" \) -prune \
            -o -regex '.+\.\(c\|h\|cpp\|cc\|hpp\|java\|rc\|xml\)$' \
            -type f -print > $FILELIST
            # grep -E "\.\w+$" | grep -v -E "\.html$|\.txt$|\.so$"
        echo " Done"
    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
" "[$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 echo -e "\033[32mFind it. Let's Go!\033[0m" \cd $T/$pathname } # , . # , cd . # . handle_symbol() { if [ $# -ne 1 ]; then echo "Usage: $FUNCNAME symbol" return 1 fi local key="$1" local prefix mm_cmd # . '+', # : source , mm . source, mm # source, source, , . prefix="${key:0:1}" if [ "${prefix}" == "${COMPILE_PREFIX}" ]; then mm_cmd="mm" # , '+' , . key=${key:1} fi # parsecfg.sh get_value_by_key # . local dir_value=$(get_value_by_key "${key}") if test -n "${dir_value}"; then # , # , , cd. \cd "${DIRECTCD_TOP_DIR}/${dir_value}" # '+', . if [ -n "${mm_cmd}" ]; then echo -e "\e[32mEnter $(pwd), execute mm.\e[0m" ${mm_cmd} fi return 0 fi echo " : '${key}' " return 2 } # , source ,OPTIND 1, # source ,getopts , OPTIND 1. OPTIND=1 while getopts "hf:ps:rlvi:ea:d:g:n:m:" opt; do # parsecfg.sh "lvi:ea:d:" . # , , . # handle_config_option() '-' , getopts # '-', ${opt} '-'. handle_config_option "-${opt}" "${OPTARG}" if [ $? -ne 127 ]; then continue fi case "$opt" in h) quickcd_show_help ;; f) open_user_config_file "$OPTARG" || return ;; p) show_top_dir ;; s) setup_top_dir "$OPTARG" || return ;; r) reset_top_dir ;; g) godir "$OPTARG" ;; n) source_and_lunch "$OPTARG" ;; m) compile_android "$OPTARG" ;; ?) echo " : , -h ." ;; esac done # $# 0, . $# OPTIND 1, # . , , symbol . # -a . . # Shell , C , . if [ $# -gt 0 -a $# -eq $((OPTIND-1)) ]; then return 0 fi # DIRECTCD_TOP_DIR . # , . , . if [ -z "${DIRECTCD_TOP_DIR}" ]; then echo -e "\e[31m , -h .\e[0m" return 2 fi # . , . check_top_dir if [ $# -eq 0 ]; then # , cd . \cd "${DIRECTCD_TOP_DIR}" # , , cd . return 0 fi # , , . shift $((OPTIND-1)) # , . # source androidcd.sh -s topdir a , , # cd a . . # source androidcd.sh a -s topdir , a # . for arg in "$@"; do handle_symbol "$arg" done return

참고 프로필 내용
이 스 크 립 트 는 기본적으로 HOME 디 렉 터 리 에 있 는 .liconfig/dirinfo.txt 파일 을 읽 습 니 다.
이 파일 에는 각 경로 의 약자 와 조정 할 디 렉 터 리 경 로 를 설정 합 니 다.
참고 프로필 내용 은 다음 과 같 습 니 다.
b|frameworks/base
fm|frameworks/base/media/java/android/media
fr|frameworks/base/core/res/res
fs|frameworks/base/services
sui|frameworks/base/packages/SystemUI/src/com/android/systemui
ps|packages/apps/Settings/

이 설정 정 보 를 기반 으로 현재 어느 디 렉 터 리 에 있 든 fs 라 는 약 자 를 매개 변수 로 사용 하면 androidcd.sh 스 크 립 트 는 cd 명령 을 실행 하여 frameworks/base/services 디 렉 터 리 에 직접 들 어 갑 니 다.
테스트 예
현재 androidcd.sh 스 크 립 트, 호출 된 parsecfg.sh 스 크 립 트 (구체 적 인 코드 는 이전 글 을 볼 수 있 음) 를 주소 지정 이 가능 한 PATH 디 렉 터 리 에 저장 합 니 다.
bash 에 별명 을 설정 합 니 다.alias c='source androidcd.sh' 프로필 을 HOME 디 렉 터 리 의. liconfig 디 렉 터 리 에 저장 합 니 다 (이 디 렉 터 리 가 없 으 면 수 동 으로 만 듭 니 다).
이후 c 명령 으로 스 크 립 트 를 실행 할 수 있 습 니 다 dirinfo.txt.
간단 한 테스트 예 는 다음 과 같다.
$ c -s android/
[android]$ c fm
[android/frameworks/base/media/java/android/media]$ c fs
[android/frameworks/base/services]$ c sui
[android/frameworks/base/packages/SystemUI/src/com/android/systemui]$ c ps
[android/packages/apps/Settings/]$ c -m dl
...... #          
[android]$ c +ps
Enter /home/android/packages/apps/Settings/, execute mm.

실행 androidcd.sh 이동 할 Android 소스 코드 루트 디 렉 터 리 경 로 를 설정 합 니 다.
실행 c -s android/ 명령 을 fm 경로 약자 에 해당 하 는 디 렉 터 리 로 이동 합 니 다.
실행 c fm 명령 을 fs 경로 약자 에 해당 하 는 디 렉 터 리 로 이동 합 니 다.c fs 명령 을 실행 하여 sui 경로 에 대응 하 는 디 렉 터 리 로 이동 합 니 다.c sui 명령 을 실행 하여 ps 경로 에 대응 하 는 디 렉 터 리 로 이동 합 니 다.c ps 스 크 립 트 를 사용 하면 폭 이 매우 큰 디 렉 터 리 사 이 를 직접 돌 릴 수 있어 편리 합 니 다.
실행 androidcd.sh 명령 이 안 드 로 이 드 소스 루트 디 렉 터 리 경 로 를 지정 하면 현재 어느 디 렉 터 리 에 있 든 실행 c -s 명령 은 자동 으로 안 드 로 이 드 소스 루트 디 렉 터 리 로 이동 하여 전체 컴 파일 됩 니 다.c -m dl 명령 을 실행 하고 ps 경로 약자 앞 에 문자 '+' 를 추가 합 니 다.
그러면 ps 에 대응 하 는 디 렉 터 리 로 전환 한 다음 안 드 로 이 드 의 mm 명령 을 자동 으로 실행 하여 디 렉 터 리 에 있 는 코드 를 컴 파일 합 니 다.
앞에서 전체 컴 파일 을 진행 할 때 안 드 로 이 드 의 source, lunch 작업 이 진행 되 었 습 니 다.
여 기 는 mm 명령 을 직접 사용 하여 컴 파일 할 수 있 습 니 다.
Android 에서 컴 파일 을 하려 면 source, lunch 작업 을 먼저 해 야 합 니 다.
현재 안 드 로 이 드 는 lunch 여 부 를 판단 할 수 있 는 명령 을 제공 하지 않 았 다.
여러 번 source, lunch 를 피하 기 위해 문자 '+' 를 사용 하여 컴 파일 을 지정 할 때 자동 으로 source, lunch 가 되 지 않 습 니 다.
즉, source, lunch 를 먼저 사용 하고 문자 '+' 를 사용 하여 컴 파일 을 지정 해 야 합 니 다.c +ps 명령 을 사용 하여 source, lunch 작업 을 할 수 있 습 니 다.
c -n lunch_combo 에서 준 dl 매개 변 수 는 기본 procject 를 컴 파일 하 는 것 을 표시 합 니 다.
이 프로젝트 는 c -m 스 크 립 트 의 DEFAULTLAUNCH_COMBO 변수 지정.
기본 설정 은 가장 자주 사용 하 는 procject 이름 입 니 다.
실제 필요 에 따라 대응 하 는 procject 이름 으로 변경 할 수 있 습 니 다.
다른 procject 를 컴 파일 하려 면 androidcd.sh 옵션 뒤에 해당 하 는 lunch 가 지 를 제공 하면 됩 니 다.-m 옵션 과 더 많은 옵션 의 용법 을 보 려 면 -m 명령 으로 구체 적 인 도움말 정 보 를 인쇄 할 수 있 습 니 다.

좋은 웹페이지 즐겨찾기