Bash script中的命令行参数处理

Bash中的script是强大的,但如果想让写出的脚本更加实用、灵活,不能简单的堆砌命令,势必要加上一些命令行参数。命令行参数除了实际的操作对象以外,还可能是一些选项(通常是用-开头的),如果还是用$1、$2这样的方式一个一个的判断参数到底是不是选项、是哪个选项就太低效了,更好的方式是用getopts,先看简单的例子:

#!/bin/bash
while getopts 'd:Dm:f:t:' OPT; do
    case $OPT in
        d)
            DEL_DAYS="$OPTARG";;
        D)
            DEL_ORIGINAL='yes';;
        f)
            DIR_FROM="$OPTARG";;
        m)
            MAILDIR_NAME="$OPTARG";;
        t)
            DIR_TO="$OPTARG";;
        ?)
            echo "Usage: `basename $0` [options] filename"
    esac
done

shift $(($OPTIND - 1))

getopts后面的字符串就是可以使用的选项列表,每个字母代表一个选项,后面带:的意味着选项除了定义本身之外,还会带上一个参数作为选项的值,比如d:在实际的使用中就会对应-d 30,选项的值就是30;getopts字符串中没有跟随:的是开关型选项,不需要再指定值,相当于true/false,只要带了这个参数就是true。如果命令行中包含了没有在getopts列表中的选项,会有警告信息,如果在整个getopts字符串前面也加上个:,就能消除警告信息了。

使用getopts识别出各个选项之后,就可以配合case来进行相应的操作了。操作中有两个相对固定的“常量”,一个是OPTARG,用来取当前选项的值,另外一个是OPTIND,代表当前选项在参数列表中的位移。注意case中的最后一个选择──?,代表这如果出现了不认识的选项,所进行的操作。

选项参数识别完成之后,如果要取剩余的其它命令行参数,可以使用shift把选项参数抹去,就像例子里面的那样,对整个参数列表进行左移操作,最左边的参数就丢失了(已经用case判断并进行了处理,不再需要了),位移的长度正好是刚才case循环完毕之后的OPTIND - 1,因为参数从1开始编号,选项处理完毕之后,正好指向剩余其它参数的第一个。在这里还要知道,getopts在处理参数的时候,处理一个开关型选项,OPTIND加1,处理一个带值的选项参数,OPTIND则会加2。

最后,真正需要处理的参数就是$1~$#了,可以用for循环依次处理。

使用getopts处理参数虽然是更加方便了,但仍然有两个小小的局限:

  1. 选项参数的格式必须是-d val,而不能是中间没有空格的-dval
  2. 所有选项参数必须写在其它参数的前面,因为getopts是从命令行前面开始处理,遇到非-开头的参数,或者选项参数结束标记--就中止了,如果中间遇到非选项的命令行参数,后面的选项参数就都取不到了。

参考

Linux下的firefox如何播放在线媒体

印象中,我Ubuntu下的firefox上网时,从来没有看到在线视频“动”过,包括观看十七大转播的时候,虽然cctv专门把首页都改成了报告专栏,但视频直播我看不到,只能看看文字转播。linux下的firefox就不能看在线视频么?显然不是,只是需要额外作点工作而已。

首先,我找到了mplayerplug-in,嫌编译太麻烦,直接下载了它为Fedora Core 6准备的rpm包,用alien转成deb,dpkg -i安装,倒是都顺利,可仍然不能播放。Mozilla Plugin Support on Linux (x86)页面上给这个插件标的状态是“Untested”,看来似乎还不够完善。

然后,又找到了别人说不错的Firefox Addon MediaPlayerConnectivity,也许是我网速太慢,居然在安装的时候遇到了错误,无法继续。

最后,又看到网上别人说装个mplayer-plugin包就可以了,apt一搜索,压根就没有嘛,不过拐了个小弯,用apt搜索了一下mplayer,发现了mozilla-mplayer,安装试试,安装时还会自动提示把刚才装的mplayerplug-in卸载,看来有戏,完成后一试,果然不错,能用,并且还挺好用呢。

想测试一下的话,可以到这里打开个在线视频试试,注意标着Inline才是在线的,External是直接提供下载的。缓存的时候如果着急,可以点右键选“Play”先看着;还有好处就是有很多选项可以定制,甚至能指定视频缓存保存位置──想保存在线视频的话就省事多了。

另外说点题外话,在制作网站时,嵌入媒体建议使用相对标准的语法,就像符合web 标准的媒体播放器代码一文中推荐的那样,比如我嵌入的wmv视频代码:

<object type="video/x-ms-wmv" data="a.wmv" width="320" height="260">
<param name="src" value="a.wmv" />
<param name="autostart" value="true" />
<param name="controller" value="true" />
</object>

使用标准的代码即简单明了,又有利于跨平台、跨浏览器的兼容。

Azureus一个非常讨厌的缺点

Azureus大概是linux下最好用的bt客户端了,虽然不敢和windows下的bitcomet等软件相媲美,但从下载管理到编码兼容性等方面综合来说,还算“堪用”。但是今天遇到了Azureus一个小缺点,不算致命,却极度讨厌和烦人。

大概起因是从设置开始的,我的Azureus设置了不备份torrent文件,于是所有的种子文件都保存在了/tmp目录下,直接被Azureus引用。而我们都知道,linux的/tmp只要重启就会全部清空,于是,当我重启之后再次启用Azureus时,发现它停留在了splash画面,一直在加载种子文件,要过很长时间,才会知道实在找不到这个种子文件了,跳过去下一个。可怜我有近20个种子文件啊,出去吃了顿饭回来,发现主界面终于能够显示出来了,但依然无法响应用户操作,等待时间遥遥无期,最后只能把~/.azureus/downloads.config和.bak文件删除了事,所有要下载的种子重新添加,这次我选择备份到某地,免得放在/tmp下重启又没了。

不知道别人有没有遇到这样的问题,我想不是每个人都能像我这样几天不关机吧。。。?

Update @ 2008-04-28

现在换mldonkey了,虽然速度不如azureus快,管理也有不方便的地方,但是,稳定压倒一切啊。