linux下shell腳本的使用——安裝madplay播放器,sed函數詳解

      今日詩詞推薦  ——青玉案·元夕,由南宋著名抗金將領辛棄疾所作。

東風夜放花千樹,更吹落、星如雨。寶馬雕車香滿路,鳳簫聲動,玉壺光轉,一夜魚龍舞。 

蛾兒雪柳黃金縷,笑語盈盈暗香去。衆裏尋他千百度,驀然回首,那人卻在,燈火闌珊處。

    

    進入正題,之前已經在移植uda1341聲卡的時候,順便安裝了madplay播放器,不過都是一步一步做的,而且源碼包也是樓主從網上找的,下載好了在進行編譯、安裝,這樣難免有些複雜,那麼我麼可以通過一個shell腳本實現一步,安裝。

    可以參照之前安裝方法:http://blog.csdn.net/qicheng777/article/details/70242075,其中有詳細介紹./Configure 的參數。

看似複雜,其實安裝第三方軟件就分爲三個步驟,但是基本都是一樣的:

  1. 生成Makefile (./Configure .....)
  2. 編譯(sudo make)
  3. 安裝(sudo make install)

shell腳本如下:

#!/bin/sh

#+--------------------------------------------------------------------------------------------
#|Description:  This shell script used to download file source code and cross compile it.
#|     Author:  GuoWenxue <[email protected]>
#|  ChangeLog:
#|           1, Initialize 1.0.0 on 2012.03.28
#+--------------------------------------------------------------------------------------------

PRJ_PATH=`pwd`                             #給變量賦值,值爲當前路徑(那是反引號,不是引號)             
if [ -z "$INST_PATH" ] ; then              #如果字符串$INST_PATH長度爲0,返回真
    INST_PATH=${PRJ_PATH}/install          
fi 

if [ ! -d $INST_PATH ] ; then        #若$INST_PATH不是目錄了,則創建該目錄
    mkdir -p $INST_PATH              #創建一個路徑來存放生成的文件
fi

ARCH=arm920t

if [ -z "$ARCH" -a $# -gt 0 ] ; then      # "$#"表示提供給腳本的參數數量,ARCH 等於爲空,並且參數大於0 。-a表示邏輯&&
   ARCH=$1
fi

sup_arch=("" "arm926t" "arm920t" )

function select_arch()         #該函數用於選擇交叉編譯器,如果只有一個交叉編譯器,就不需要調用此函數
{
   echo "Current support ARCH: "
   i=1
   len=${#sup_arch[*]}

   while [ $i -lt $len ]; do    #這裏是while循環,i從1開始到小於$len
     echo "$i: ${sup_arch[$i]}"  #分別打印出 “ 空白, arm926t,arm920t”
     let i++;                   #let用於數學運算,和expr類似
   done

   echo "Please select: "
   index=
   read index                    #read是讀取命令,需要你從鍵盤上輸入給index賦值(1, 2, 3)
   ARCH=${sup_arch[$index]}      #數組引用   
}

#這裏是一個解壓縮函數,用來解壓縮下載的文件
function decompress_packet()
(
   echo "+---------------------------------------------+"
   echo "|  Decompress $1 now"  
   echo "+---------------------------------------------+"

    ftype=`file "$1"`    #ftype是獲得的文件類型,這裏$1是位置參數,表示第二個參數,和C中的argv[1]類似
    case "$ftype" in        #下面是case語句,對應不同的壓縮類型,用不同解壓縮語句
       "$1: Zip archive"*)
           unzip "$1" ;;
       "$1: gzip compressed"*)
           if [ 0 != `expr "$1" : ".*.tar.*" ` ] ; then  
               tar -xzf $1
           else
               gzip -d "$1"                            
           fi ;;
       "$1: bzip2 compressed"*)
           if [ 0 != `expr "$1" : ".*.tar.*" ` ] ; then  #如果該文件中間含有tar,可能爲.tar.bz2
               tar -xjf $1
           else
               bunzip2 "$1"                              #或者爲.bz2
           fi ;;
       "$1: POSIX tar archive"*)
           tar -xf "$1" ;;
       *)
          echo "$1 is unknow compress format";;
    esac
)


if [ -z "$CROSS" ] ; then   #先判斷CROSS和ARCH都爲空,然後賦值!
   if [ -z $ARCH ] ; then
      select_arch           #調用交叉編譯器選擇函數
   fi
   CROSS="/opt/buildroot-2012.08/${ARCH}/usr/bin/arm-linux-"   #將交叉編譯器地址給CROSS
fi

CROSS_PATH=`dirname $CROSS`      #dirname命令獲得絕對路徑
export PATH=${CROSS_PATH}:$PATH  #下面是用export給相應變量賦值,將原來編譯器命令改成交叉編譯器命令
export CC=${CROSS}gcc
export CXX=${CROSS}g++
export AR=${CROSS}ar
export AS=${CROSS}as
export LD=${CROSS}ld
export NM=${CROSS}nm
export RANLIB=${CROSS}ranlib
export STRIP=${CROSS}strip

LIBMAD_NAME=libmad-0.15.1b
LIBMAD_DL_ADDR=ftp://ftp.mars.org/pub/mpeg/$LIBMAD_NAME.tar.gz
if [ ! -d ${INST_PATH}/libmad/include ]; then

    echo "+------------------------------------------------------------------+"
    echo "|          Build libmad(MPEG Audio Decoder) for $ARCH "
    echo "| Crosstool:  $CROSS"
    echo "+------------------------------------------------------------------+"

    if [ ! -s $LIBMAD_NAME.tar.gz ] ; then   #若文件名存在,並且長度大於0
        wget $LIBMAD_DL_ADDR                 #下載
    fi

    decompress_packet $LIBMAD_NAME.tar.gz    #解壓縮
    cd $LIBMAD_NAME                          #進入該文件
    ./configure --enable-fpm=arm --host=arm-linux --disable-shared \
    --disable-debugging --prefix=$INST_PATH/libmad CC=${CC}    #編譯生成Makefile

    #Modify the Makefile to fix the cross compiler bug
    sed -i -e 's/-fforce-mem//' Makefile   #刪除Makefile中所有“-fforce-mem”字符串 

    make && make install                   #make和安裝

    cd -                                   #回到上一次操作目錄
fi

MADID3_NAME=libid3tag-0.15.1b
MADID3_DL_ADDR=ftp://ftp.mars.org/pub/mpeg/$MADID3_NAME.tar.gz
if [ ! -d ${INST_PATH}/madid3 ]; then

    echo "+------------------------------------------------------------------+"
    echo "|          Build madid3(MPEG Audio Decoder) for $ARCH "
    echo "| Crosstool:  $CROSS"
    echo "+------------------------------------------------------------------+"

    if [ ! -s $MADID3_NAME.tar.gz ] ; then 
        wget $MADID3_DL_ADDR
    fi

    decompress_packet $MADID3_NAME.tar.gz
    cd $MADID3_NAME
    ./configure --host=arm-linux --prefix=$INST_PATH/madid3 --disable-shared --disable-debugging \
    CFLAGS=-I${INST_PATH}/libmad/include LDFLAGS=-L${INST_PATH}/libmad/lib CC=${CC}

    #Modify the Makefile to fix the cross compiler bug
    sed -i -e 's/-fforce-mem//' Makefile   

    make && make install

    cd -
fi

MADPLAY_NAME=madplay-0.15.2b
MADPLAY_DL_ADDR=ftp://ftp.mars.org/pub/mpeg/$MADPLAY_NAME.tar.gz
if [ ! -d ${INST_PATH}/madplay ]; then

    echo "+------------------------------------------------------------------+"
    echo "|          Build madplay(MPEG Audio Decoder Player) for $ARCH "
    echo "| Crosstool:  $CROSS"
    echo "+------------------------------------------------------------------+"

    if [ ! -s $MADPLAY_NAME.tar.gz ] ; then
        wget $MADPLAY_DL_ADDR
    fi

    decompress_packet $MADPLAY_NAME.tar.gz
    cd $MADPLAY_NAME
    ./configure --host=arm-linux --prefix=$INST_PATH/madplay --disable-shared --disable-debugging \
    CFLAGS="-I${INST_PATH}/libmad/include -I${INST_PATH}/madid3/include " \
    LDFLAGS="-L${INST_PATH}/libmad/lib -L${INST_PATH}/madid3/lib" CC=${CC}

    #Modify the Makefile to fix the cross compiler bug
    sed -i -e 's/-fforce-mem//' Makefile

    make && make install

    cd -
fi

APP_NAME="MPlayer-1.0rc3"
PACK_SUFIX="tar.bz2"
DL_ADDR="http://www.mplayerhq.hu/MPlayer/releases/MPlayer-1.0rc3.tar.bz2"

echo "+------------------------------------------------------------------+"
echo "|          Build $APP_NAME for $ARCH "
echo "| Crosstool:  $CROSS"
echo "+------------------------------------------------------------------+"

# Download source code packet
if [ ! -s $APP_NAME.$PACK_SUFIX ] ; then
   echo "+------------------------------------------------------------------+"
   echo "|  Download $APP_NAME.$PACK_SUFIX  now "  
   echo "+------------------------------------------------------------------+"

   wget $DL_ADDR
fi

# Decompress source code packet
if [ -d $APP_NAME ] ; then   #若有$APP_NAME文件夾,則先刪除它
    rm -rf $APP_NAME
fi
decompress_packet $APP_NAME.$PACK_SUFIX


cd $APP_NAME

#Modify the source code to fix the build bug
FILE=libmpeg2/motion_comp_arm_s.S      
line=`sed -n '/.text/=' $FILE`        #打印該目錄下libmpeg2/motion_comp_arm_s.S文件包含 .text 這行的行號   
line=`expr $line - 1`                 #跳轉到上一行   
sed -i -e `expr $line`a"#ifndef HAVE_PLD" $FILE   #  “a”表示在後面添加一行
sed -i -e `expr $line + 1`a"    .macro pld reg" $FILE
sed -i -e `expr $line + 2`a"    .endm" $FILE
sed -i -e `expr $line + 3`a"#endif" $FILE

./configure --prefix=$INST_PATH/mplayer --cc=arm-linux-gcc  --ar=arm-linux-ar  \
 --ranlib=arm-linux-ranlib --disable-gui   \
 --target=arm-armv4-linux --host-cc=gcc  --disable-freetype\
 --enable-fbdev --disable-mencoder --disable-sdl --disable-live  --disable-dvdread \
 --disable-libdvdcss-internal --disable-x11 --enable-cross-compile  --disable-mp3lib \
 --enable-ass  \
 --disable-dvdnav  --disable-dvdread-internal    --disable-jpeg --disable-tga \
 --disable-dvbhead --disable-pnm --disable-tv --disable-ivtv \
 --disable-fontconfig --disable-xanim --disable-win32dll --disable-armv5te --disable-armv6

    make && make install
    ${CROSS}strip $INST_PATH/mplayer/bin/mplayer   #對其進行strip,對程序瘦身
cd -

    把代碼放在一個文件夾後,用命令 sh mp3.sh 就可以嘟嘟一直跑了,一步到位,毫不費力!

注:

    值得一提的是,shell腳本不同於其他編程語言,變量無需定義,直接對其變量賦值就包含定義了。變量通過“$” 來引用。

    程序中對linux命令引用用反引號(鍵盤上在ESC鍵下面),而不是單引號,比如第一行。

    函數調用時無需帶括號

    if等控制語句,例如 if [ ! -d ${INST_PATH}/madid3 ] ,if後一定有空格,然後中括號最前面和最後都有空格。  


一、符號:

  • 雙引號括起來是當做普通字符。$    `(反引號)     \  (反斜槓)    除外。
  • $   表示變量替換
  • `    表示命令替換(反引號)
  • \    表示不要對其後字符做特殊處理。($    `    \    換行符 除外)
  • 單引號括起來的當做普通字符處理,包括特殊字符
二、數組:

可直接賦值 a[0]=beijing

                    a[1]=shanghai
也可以用declare 命令顯示聲明數組   declare -a 數組名
引用數組:echo  ${ a[0] }
批量賦值:a=(this is an exp for you)        則a[0]=this


三、read命令(從鍵盤上讀入數據):
[yangni@yangni ~]$ read a b c               #讀取三個自定義變量
myname is haha                               #輸入三個變量的值。
[yangni@yangni ~]$ echo $a $b $c         

myname is haha

四、位置參數:
ftype=`file "$1"`    #ftype是獲得的文件類型,這裏$1是位置參數,表示第二個參數,和C中的argv[1]類似
    case "$ftype" in        #下面是case語句,對應不同的壓縮類型,用不同解壓縮語句
       "$1: Zip archive"*)
           unzip "$1" ;;
       "$1: gzip compressed"*)
           if [ 0 != `expr "$1" : ".*.tar.*" ` ] ; then   #檢測$1中中間是否含有 tar
               tar -xzf $1
           else
               gzip -d "$1"                            
           fi ;;
     引用上面一段代碼,我們可以看出這是一個case語句,而$1則是第二個參數,類似於C中的argv[1]類似。例如調用的時候是這樣的:
      decompress_packet    $LIBMAD_NAME.tar.gz
函數名爲第一個參數,變量爲第二個參數,以此類推若有三個參數,則可用$2引用。

五、sed函數詳解:
(1)sed [選項]   [定址commands]  [inputfile]
關於定址:
定址可以是0個、1個、2個;通知sed去處理文件的哪幾行。
0個:沒有定址,處理文件的所有行
1個:行號,處理行號所在位置的行
2個:行號、正則表達式,處理被行號或正則表達式包起來的行

(2)選項:
 --version            顯示sed版本hao
 --help                顯示幫助文檔
 -n 關閉默認輸出,默認將自動打印所有行
 -e 多點編輯,允許多個腳本指令被執行。
 -r 支持擴展正則+ ? () {} |
 -i 可以修改原文件慎用!
 -f 支持使用腳本

(3)命令:
     p     打印行
     d     刪除行
     s     替換
     n     替換第幾個匹內容
     w    另存爲
     a     之後添加一行
     i      當前行之前插入文本
     y     替換匹配內容

例如:
1、刪除(d):
   (1)刪除文件aaa.c第一行和第三行:
     sed -e  '1d'  -e  '3d'  aaa.c    (等價於sed -e  '1d;3d'  aaa.c)
     如果確定要刪除原文件,則添加-i選項:
     sed -i -e '1d' -i -e '2d' aaa.c  
  (2)刪除aaa.c文件1到7行:
     sed -e  '1~3d'  aaa.c

2、打印(p) :
  (1)打印文件aaa.c第一行和第三行:
       sed -n  '1p;3p'  aaa.c
  (2)打印文件aaa.c一到三行:
       sed -n  '1,3p'  aaa.c
  (3每隔兩行打印一次:(3-1)
      sed -n  '1~3p'   aaa.c
  (4)打印另一種表示法:(打印從 包含字符b的行,到包含字符c的行,如果多行包含C,匹配最近的行 )
     sed -n  '/b/,/c/p' aaa.c 
     每個字符前都需要加   /   ,相當於分隔符,用於隔斷

3、查找和替換:

語法:

      '[address] s/pattern/replacement/flags'

                         old     new

flags:

           n:1-512 之間的正整數,表示替換模式裏面出現的第幾次內容

           p:打印

           g:全局修改

           w:另存爲


(1)將hate 換成love,她就會愛你了
       sed   's/hate/love/' aaa.c

      sed   's/hate/love/g' aaa.c  : 後面加個g, 全部替換

(2)每行前面添加   # 
         sed  ' s/^/#/ '   aaa.c
     
(3)刪除每一行第一個字符:(同理,刪除第二個字符將1改成2)
         sed  -i 's/^.//1 '   aaa.c
    
(4)插入:
      sed  '2i hello' aaa.c    第二行前插入 (後面插入把i 改成 a)


舉完例後,我們對代碼中用到sed地方進行分析:
FILE=libmpeg2/motion_comp_arm_s.S      
line=`sed -n '/.text/=' $FILE`        #打印該目錄下libmpeg2/motion_comp_arm_s.S文件包含 .text 這行的行號   
line=`expr $line - 1`                 #跳轉到上一行   
sed -i -e `expr $line`a"#ifndef HAVE_PLD" $FILE       #“a”表示在後面添加一行   
sed -i -e `expr $line + 1`a"    .macro pld reg" $FILE
sed -i -e `expr $line + 2`a"    .endm" $FILE
sed -i -e `expr $line + 3`a"#endif" $FILE
   第一行:給定文件名。
    第二行:找到文件中含有“.text”字符的行,並打印行號。
    第三行:行號減一(跳轉到前一行)
    第四行以後:沒插入一段字符後把行號加1,相當於插入完後就回車。
所以修改以後是這樣的:
    
就相當於在前面插入了4行了。
      這裏的expr和let使用類似,用於各種運算,後面再對shell循環語句,以及一些函數做介紹。

    

特殊變量列表
變量 含義
$0 當前腳本的文件名
$n 傳遞給腳本或函數的參數。n 是一個數字,表示第幾個參數。例如,第一個參數是$1,第二個參數是$2。
$# 傳遞給腳本或函數的參數個數。
$* 傳遞給腳本或函數的所有參數。
$@ 傳遞給腳本或函數的所有參數。被雙引號(" ")包含時,與 $* 稍有不同,下面將會講到。
$? 上個命令的退出狀態,或函數的返回值。
$$ 當前Shell進程ID。對於 Shell 腳本,就是這些腳本所在的進程ID。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章