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 <guowenxue@gmail.com>
#|  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。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值