Linux手机DIY.Shell应用扩展一.随机来电铃声(E680系列)
草木瓜
2007-03-18
一、什么是Shell
在开始正题前,总习惯于从网上抄一些东东,来“丰富”下文章的内容。 Shell是一种具备特殊功能的程序,它是介于使用者和 UNIX/Linux 操作系统核心程序(kernel)间的一个接口。换而言之,就是你平常要想操作 UNIX/Linux 的话,就需要通过Shell来进行。 为什么我们说 Shell 是一种介于系统核心程序与使用者间的中介者呢?读过操作系统概论的读者们都知道操作系统是一个系统资源的管理者与分配者,当用户有请求时,得向系统提出;从操作系统的角度来看,它也必须防止使用者因为错误的操作而造成系统的损害。众所周知,对计算机系统下命令得通过预定义的命令或程序。 Shell本身就是一个程序,一个已经由别人写好并且编译过的程序,它从输入设备读取命令,将其转换为计算机操作系统可以理解的机器码,然后执行。各种操作系统其实都有它自己的Shell,以大家容易理解的DOS为例,它的Shell就是command.com文件。Windows下的DOS命令dir,copy等之类都是通过其解释执行的。
Unix/Linux系统下Shell也有多种。常用的有Bourne Shell(sh)、C-Shell(csh)、Korn Shell(ksh)和Bourne Again Shell(bash)。 Bourne Shell(sh)是AT&T Bell实验室的Steven Bourne为AT&T的Unix开发的,它是Unix的默认Shell,也是其它Shell的开发基础。Bourne Shell在编程方面相当优秀,但在处理与用户的交互方面不如其它几种Shell。 C Shell(csh)是加州伯克利大学的Bill Joy为BSD Unix开发的,与sh不同,它的语法与C语言很相似。它提供了Bourne Shell所不能处理的用户交互特征,如命令补全、命令别名、历史命令替换等。但是,C Shell与BourneShell并不兼容。 Korn Shell(ksh)是AT&T Bell实验室的David Korn开发的,它集合了C Shell和Bourne Shell的优点,并且与Bourne Shell向下完全兼容。Korn Shell的效率很高,其命令交互界面和编程交互界面都很好。 Bourne Again Shell(bash)是自由软件基金会(GNU)开发的一个Shell,它是Linux系统中一个默认的Shell。Bash不但与Bourne Shell兼容,还继承了C Shell、Korn Shell等众多优点。
<Linux手机DIY系列:http://blog.csdn.net/liwei_cmg/category/241839.aspx>
二、随机来电铃音的总体思路
随机来电铃这东西早就有人实现,方法也是多种多样的。具体这个东西的作用是仁者见仁,智者见智。个人觉得偶尔用用感觉也不错,重要的是挖掘Shell扩展手机应用的潜力。而且Shell对大多数人来说,上手也比较容易,相关资料也十分多。夏新E600和飞利浦968的安装包就是通过简单的一些Shell来实现。可以说,研究这些手机最为关键的部分,就是Shell!
现在大多数Linux智能手机,铃音配置都是以文本格式存在,可见理论上直接修改这类文件就可以轻松实现对短信息和手机铃声进行更改。但在实际操作过程中发现,直接去修改这个文件的话,E680是不能够即时生效的,需要重新设置刷新才行。 后经一些尝试发现,先设置好铃音的配置文件,修改实际的对应铃声文件最为有效。 AlertRingTone1 = /mmc/mmca1/Music/Ring/ring.mp3 AlertRingTone2 = /mmc/mmca1/Music/Ring/ring.mp3 AlertRingerIDs = 0 AlertStyleIconDir = /usr/language/alertStyle/ AlertSystemVolume = 10 AlertTextMsg = /mmc/mmca1/Music/Ring/message.mp3 [AlertTextMsg]对应短信息铃声,[AlertRingTone1]对应来电铃声,这个配置文件我不去改它,动态修改的是ring.mp3,message.mp3的实际文件。修改的过程仅仅就是mv Artist.mp3 ring.mp3这么简单。
下面需要解决的就是修改时机和随即性两个问题。我这里显然是一个在后台不断循环运行的Shell脚本,当短信息或者来电时,系统会启动alterprocss这个进程,这个脚本自然能检测的这个进程相关信息,并修改相应的铃声文件。至于随机性,其实来电本身就是随机事件,这里只用了一个伪随即方法,即根据来电的时间信息,进行铃声文件选择。
三、脚本文件全内容
001 #!/bin/bash002 003 004 #当前路径005 Path_Current=/mmc/mmca1/soft/ring006 007 #日志文件008 File_Log=$Path_Current/log.txt009 010 #来电铃声目录011 if [ ! -f $Path_Current/ring.txt ]012 then013 echo /mmc/mmca1/Music/Game > $Path_Current/ring.txt014 fi015 Path_Ring=`cat $Path_Current/ring.txt`016 017 #短信息铃声目录018 if [ ! -f $Path_Current/msg.txt ]019 then020 echo /mmc/mmca1/Music/Game > $Path_Current/msg.txt021 fi022 Path_Message=`cat $Path_Current/msg.txt`023 024 #固定来电消息文件目录025 if [ ! -f $Path_Current/default.txt ]026 then027 echo /mmc/mmca1/Music/Ring > $Path_Current/default.txt028 IsReset=1029 else030 IsReset=0031 fi032 Path_Default=`cat $Path_Current/default.txt`033 034 035 #系统预定义短信最长秒036 if [ ! -f $Path_Current/maxmessage.txt ]037 then038 echo '15' > $Path_Current/maxmessage.txt039 fi040 Var_MsgMaxSec $Path_Current/maxmessage.txt`041 042 #指定的短消息铃声043 Default_MessageFile=$Path_Default/message.mp3044 #指定的电话铃声045 Default_RingFile=$Path_Default/ring.mp3046 047 048 #指令集049 File_Busybox=/mmc/mmca1/tmp/busybox050 #临时处理配置的文件051 File_Sed=$Path_Current/tmpsed.txt052 #临时文件大声053 File_TmpRingLoud=$Path_Current/tmpRingLoud.pts054 #临时文件轻声055 File_TmpRingSoft=$Path_Current/tmpRingSoft.pts056 057 #临时进程文件058 File_TmpProcess=$Path_Current/tmpgrep.txt059 060 061 #临时可供随机的文件列表062 FileList_Tmp=filelist.txt063 064 #系统大声的配置文件065 File_RingLoud=/ezxlocal/download/appwrite/setup/RingLoud.pts066 #系统轻声的配置文件067 File_RingSoft=/ezxlocal/download/appwrite/setup/RingSoft.pts068 069 070 echo '====== Random Ring ======' >> $File_Log071 echo `$File_Busybox date` ' : Start' >> $File_Log 072 073 074 if [ '$IsReset' = '1' ] 075 then076 077 echo `$File_Busybox date` ' : Create New PtsFile' >> $File_Log 078 079 #生成新的配置文件080 echo '#!/bin/sed -f' > $File_Sed081 echo '/AlertRingTone1/ c' >> $File_Sed082 echo 'AlertRingTone1 = $Default_RingFile' >> $File_Sed083 echo '/AlertRingTone2/ c' >> $File_Sed084 echo 'AlertRingTone2 = $Default_RingFile' >> $File_Sed085 echo '/AlertTextMsg/ c' >> $File_Sed086 echo 'AlertTextMsg = $Default_MessageFile' >> $File_Sed087 088 #echo $File_Sed ' ' $File_RingLoud089 $File_Sed $File_RingLoud > $File_TmpRingLoud090 $File_Sed $File_RingSoft > $File_TmpRingSoft091 092 cp -f $File_TmpRingLoud $File_RingLoud093 cp -f $File_TmpRingSoft $File_RingSoft094 095 fi096 097 #$File_Busybox renice -20 $$098 echo $$ > $Path_Current/proc.txt099 100 echo `$File_Busybox date` ' : ProcessID ' $$ >> $File_Log 101 102 while103 104 do105 106 ProcID_Alert=`pidof alertprocess`107 108 if [ '$ProcID_Alert' = '' ]109 then110 111 echo 'Runing ...'112 sleep 1s113 114 else115 116 echo `$File_Busybox date` ' : AlertProcessID ' $ProcID_Alert >> $File_Log117 118 ps -ef | grep '.mp3' | grep -v grep > $File_TmpProcess119 120 if grep 'ring.mp3' $File_TmpProcess | grep -v grep121 then122 HaveSession='PHONE'123 echo `$File_Busybox date` ' : Have Phone ' >> $File_Log124 fi 125 126 if grep 'message.mp3' $File_TmpProcess | grep -v grep127 then128 HaveSession='MESSAGE'129 echo `$File_Busybox date` ' : Have Message ' >> $File_Log130 fi 131 132 #循环变量133 i=0134 135 while [ ! '$ProcID_Alert' = '' ]136 do 137 ProcID_Alert=`pidof alertprocess`138 sleep 1s139 #echo 'sleep now!'140 141 if [ '$HaveSession' = 'MESSAGE' ]142 then143 if [ '$i' = '$Var_MsgMaxSecond' ]144 then145 kill -9 `pidof alertprocess`146 else147 i=$(($i+1))148 fi149 fi 150 151 done152 153 Value_Base=`$File_Busybox date -u ’+%M%S’`154 155 #echo 'OK'156 157 if [ '$HaveSession' = 'PHONE' ]158 then159 160 #处理随机来铃161 cd $Path_Ring162 rm $FileList_Tmp163 find . -name ’*[m,M][p,P]3’ | sed ’s/^.//g’ > $FileList_Tmp164 Max_Count=`$File_Busybox wc $FileList_Tmp | $File_Busybox awk ’{print $1}’`165 Value_Round=$(($Value_Base % $Max_Count + 1))166 167 #echo $Value_Round168 169 Name_NextRing=`sed -n '$Value_Round p' $Path_Ring/$FileList_Tmp`170 rm $FileList_Tmp171 172 if [ -f $Default_RingFile ]173 then174 175 if [ -f $Path_Current/prering.txt ] 176 then177 #echo178 mv '$Default_RingFile' '`cat $Path_Current/prering.txt`'179 echo `$File_Busybox date` ' : mv $Default_RingFile' '`cat $Path_Current/prering.txt`' >> $File_Log180 else181 rm '$Default_RingFile'182 echo `$File_Busybox date` ' : rm $Default_RingFile' >> $File_Log183 fi184 185 fi186 187 #echo 188 mv '$Path_Ring$Name_NextRing' '$Default_RingFile'189 echo $Path_Ring$Name_NextRing > $Path_Current/prering.txt 190 echo `$File_Busybox date` ' : mv $Path_Ring$Name_NextRing' '$Default_RingFile' >> $File_Log191 192 fi 193 194 if [ '$HaveSession' = 'MESSAGE' ]195 then196 197 #处理随机短信息198 cd $Path_Message199 rm $FileList_Tmp200 find . -name ’*[m,M][p,P]3’ | sed ’s/^.//g’ > $FileList_Tmp201 Max_Count=`$File_Busybox wc $FileList_Tmp | $File_Busybox awk ’{print $1}’`202 Value_Round=$(($Value_Base % $Max_Count + 1))203 204 #echo $Value_Round205 206 Name_NextMessage=`sed -n '$Value_Round p' $Path_Message/$FileList_Tmp`207 rm $FileList_Tmp208 209 210 if [ -f $Default_MessageFile ]211 then212 213 if [ -f $Path_Current/premsg.txt ] 214 then215 #echo 216 mv '$Default_MessageFile' '`cat $Path_Current/premsg.txt`'217 echo `$File_Busybox date` ' : mv $Default_MessageFile' '`cat $Path_Current/premsg.txt`' >> $File_Log218 else219 rm '$Default_MessageFile'220 echo `$File_Busybox date` ' : rm $Default_MessageFile' >> $File_Log221 fi222 223 fi224 225 #echo 226 mv '$Path_Message$Name_NextMessage' '$Default_MessageFile'227 echo $Path_Message$Name_NextMessage > $Path_Current/premsg.txt228 echo `$File_Busybox date` ' : mv $Path_Message$Name_NextMessage' '$Default_MessageFile' >> $File_Log229 230 231 #kill -9 `pidof alertprocess`232 #cp -f $Path_Ring/$Name_NextRing233 234 fi235 236 237 sleep 1s238 239 fi240 241 242 done
四、脚本文件说明
这个脚本虽然有点注释,但乍一看还是有点乱,这里作一些补充。 脚本主要分“变量定义和预处理”<001-100>“主循环”<101-242>两部分。 A.“变量定义和预处理” 这个脚本命名随意,但是存放路径必须与<005>所定义的路径相同。(注:这里也完全可以用`pwd`来代替。) 脚本运行后会在当前路径下生成如下文件: log.txt 记录整个运行日志 ring.txt 记录来电铃音随机选择的目录,目前脚本会包含该目录的所有子 目录 msg.txt 记录短信息铃音随即选择的目录,同上 default.txt 记录来电的固定文件的目录, maxmessage.txt 记录短信的最长响铃时间 此外还产生了一些tmp的临时文件。 B.“主循环” 系统总会不断执行<106>这条语句,经过一些尝试,使用pidof效率是最高的,否则后台一旦起了Shell,系统整体速度会略有减慢。 Shell进程运行后,一旦有来电,会自动执行<114>下面的内容,<118>-<130>进行进程信息提取,判断是短信息还是来电。<132>-<151>是对短信的特别处理,如超过最大响铃时间,即终止响铃。 <157>-<234>是对随即铃声文件的真正处理。即每次来电,将文件mv,从而保证下次响铃的随机性。 这个脚本主要用了busybox,原因是系统的原来的功能比较有限。 五、后记
本脚本涉及的命令是十分常见的:ps,sed,find,grep,date等,所要注意的是E680是用bash,对于$(())的数值运算表达方式,其它shell并不能通用。 对于Linux手机新手来说,现在只需要一些耐心去消化脚本所使用的Shell命令和Shell规范。