测试了一下用面向对象的思维方式进行 Bash 脚本编程,然后用easybashgui ( http://sites.google.com/site/easybashgui ) 图形库作为 GUI 前端。下面是一个简单的测试。
需求:
主程序 testor.sh (或guitestor.sh)调用配置管理器 configurator.sh 进行配置管理和转换器 videoconvertor.sh 进行模拟转换操作。
配置器和转换器均包括相应的 init() 初始化函数和 destroy() 清除函数,数据设置和获取函数 set() 及 get()。configurator.sh 还包括工作函数 doconvert()。
主要目的是对各个工作模块提供一个面向对象的工作方式,但是究竟对实际的生产环境编程是否有用还有待进一步的验证。
下面是两个配置文件及两个类和两个测试主程序的源码。其中的 easybashgui 实际上是一个利用 dialog(terminal) 或者 Xdialog(gtk1), zenity(gtk2) 等程序的简单图形界面交互 bash 函数库。也可以直接用 dialog 系统程序写。
不过,感觉用面向对象的思维方式写 Bash 脚本始终有点别扭,而且图形界面的交互能力相比 GTK 之类很有限,感觉想作为商业化的程序还是欠了点。以后有需要的时候用这种“面向对象”的思维方式完整的写一个程序,然后对比一般的面向过程的 Bash 脚本编程试试,看看有没有继续学习这种 Bash 脚本编程的价值。
另外,试了一下用 shc ( http://www.datsi.fi.upm.es/~frosal/sources/shc.html ) 把 Bash 脚本加密成二进制可执行文件,因为加密后的文件改变了原脚本文件的内容,所以不能在一个脚本中分别的引入其它的加密脚本进行协同工作,但是可以把所有脚本文件连成一个脚本文件再加密。另外,也可以使用源码混淆器 ( shell script obfuscator :http://www.comp.eonworks.com/scripts/obfuscate_shell_script-20011012.html )把脚本变得人工难以阅读来进行一定程度的源码保护。不过,这些加密措施对于技术高手来说可能都不算什么。并且在网上已经有针对 shc 加密文件的反编译方法。
听说,现在国内商业开源的环境不太好,而我想做的东西如果现在没有充分的理由开源,以后再想回转来闭源就难了。所以,不管如何,暂时不准备开源。当然,我的系统是构建在开源平台之上,不管赚钱不赚钱,最好还是遵守相关的开源协议好。另外,想了一下,开发开源平台上的闭源软件也算是丰富开源平台上的应用吧。我想,认识开源,利用开源,回馈开源,应该都是有个环境、有个过程的吧。边走边看边想边做吧。
主配置文件:./confs/mobile.conf
logfile="./logs/mobile.log"
视频转换配置文件 ./confs/video.conf
resolution=300x200:format=3gp
配置管理器 ./configurator.sh
#!/bin/bash
# config file operator
. ./confs/mobile.conf
configurator_file=""
configurator_set ()
{
while [ -n "$*" ]; do
case "$1" in
-c)
shift
configurator_file="$1"
shift
;;
-o)
shift
echo "$@" > $configurator_file
break
;;
esac
done
echo "INFO: set config values: `cat $configurator_file` to $configurator_file." >> $logfile
}
configurator_get ()
{
while [ -n "$*" ]; do
case "$1" in
-c)
shift
configurator_file="$1"
shift
;;
esac
done
cat $configurator_file
echo "INFO: got config values: `cat $configurator_file` from $configurator_file." >> $logfile
}
configurator_init()
{
echo "INFO: `date`, started configurator." >> $logfile
configurator_file=""
}
configurator_destroy()
{
configurator_file=""
echo "INFO: `date`, ended configurator." >> $logfile
}
转换器: ./videoconvertor.sh
#!/bin/bash
# video convert operator
. ./configurator.sh
videoconvertor_input=""
videoconvertor_output=""
videoconvertor_option=""
videoconvertor_set ()
{
local infostr=""
while [ -n "$*" ]; do
case "$1" in
-c)
configurator_init
videoconvertor_option=( `configurator_get -c ./confs/video.conf` )
configurator_destroy
shift
;;
-i)
shift
videoconvertor_input="$1"
shift
;;
-O)
shift
videoconvertor_output="$1"
shift
;;
-o)
shift
videoconvertor_option="$1"
shift
;;
esac
done
infostr="
videoconvertor_input=$videoconvertor_input
videoconvertor_output=$videoconvertor_output
videoconvertor_option=$videoconvertor_option"
echo "INFO: set videoconvertor values: $infostr." >> $logfile
}
videoconvertor_get ()
{
local infostr=""
echo "videoconvertor_input=$videoconvertor_input"
echo "videoconvertor_output=$videoconvertor_output"
echo "videoconvertor_option=$videoconvertor_option"
infostr="
videoconvertor_input=$videoconvertor_input
videoconvertor_output=$videoconvertor_output
videoconvertor_option=$videoconvertor_option"
echo "INFO: got videoconvertor values: $infostr from parameters." >> $logfile
}
videoconvertor_doconvert()
{
echo "INFO: converted $videoconvertor_input to $videoconvertor_output with option $videoconvertor_option ok." >> $logfile
for i in `seq 10`; do
echo "$$: $i doing convert $videoconvertor_input to $videoconvertor_output with option $videoconvertor_option..."
sleep 1
done
}
videoconvertor_init()
{
echo "INFO: `date`, started videoconvertor." >> $logfile
videoconvertor_input=""
videoconvertor_output=""
videoconvertor_option=""
}
videoconvertor_destroy()
{
videoconvertor_input=""
videoconvertor_output=""
videoconvertor_option=""
echo "INFO: `date`, ended videoconvertor." >> $logfile
}
无图形界面测试主程序: ./testor.sh
#!/bin/bash
. ./configurator.sh
configurator_init
configurator_set -c ./confs/video.conf -o resolution="300x200":format="mp4"
config_values=( `configurator_get -c ./confs/video.conf` )
configurator_destroy
echo
echo "test videoconvertor.sh begin..."
. ./videoconvertor.sh
echo "1 $videoconvertor_option"
videoconvertor_init
echo "2 $videoconvertor_option"
videoconvertor_set -c -i /pathto/input -O /pathto/ouput
echo "3 $videoconvertor_option"
videoparameters=( `videoconvertor_get` )
echo "4 $videoconvertor_option"
videoconvertor_doconvert &
videoconvertor_destroy
echo "5 $videoconvertor_option"
echo "test videoconvertor.sh 2 begin..."
echo "1 $videoconvertor_option"
videoconvertor_init
echo "2 $videoconvertor_option"
videoconvertor_set -c -i /pathto/input2 -O /pathto/ouput2 -o resolution="320x220":format="3gp"
echo "3 $videoconvertor_option"
videoparameters=( `videoconvertor_get` )
echo "4 $videoconvertor_option"
videoconvertor_doconvert &
videoconvertor_destroy
echo "5 $videoconvertor_option"
exit 0
带图形界面测试主程序: ./guitestor.sh
#!/bin/bash
. ./configurator.sh
. easybashgui
message "现在测试图形界面效果..."
menu \
"视频转换设置..." \
"音频提取设置..." \
"______________________________________" \
"视频转换..." \
"音频提取..." \
"______________________________________" \
"退出->"
selectitem=`cat ${dir_tmp}/${file_tmp}`; clean_temp
if [ "$selectitem" == "视频转换设置..." ]; then
configurator_init
message "你可以为不同的手机生成不同的视频转换配置文件,\n点击\"确定\"输入配置文件名称..."
input 1 "defaultvideo.conf"
conf_file=`cat ${dir_tmp}/${file_tmp}`; clean_temp
echo "conf_file is $conf_file"
message "点击\"确定\"选择视频转换参数,\n注意:相同的参数只能选择其中一项..."
list "分辨率:301x2001" "分辨率:401x301" "格式:3gp" "格式:mp4"
options=( `cat ${dir_tmp}/${file_tmp}` ); clean_temp
clean_temp
echo "options is ${options[@]}"
options2=`echo ${options[@]} | sed "s/ //" | sed "s/分辨率:/resolution=/" | sed "s/格式:/:format=/"`
echo $options2
configurator_set -c ./confs/$conf_file -o $options2
config_values=( `configurator_get -c ./confs/video.conf` )
configurator_destroy
echo
elif [ "$selectitem" == "视频转换..." ]; then
echo "test videoconvertor.sh begin..."
. ./videoconvertor.sh
configfile="./confs/defaultvideo.conf"
if ! $( question "是否使用默认视频转换设置?\n点击“Cancel”自己选择配置文件" ); then
menu `cd ./confs; ls *`
selectitem=`cat ${dir_tmp}/${file_tmp}`; clean_temp
echo $selectitem
configfile="./confs/$selectitem"
fi
echo "1 $videoconvertor_option"
videoconvertor_init
echo "2 $videoconvertor_option"
configurator_init
config_values=( `configurator_get -c $configfile` )
configurator_destroy
videoconvertor_set -c -i /pathto/input -O /pathto/ouput -o $config_values
echo "3 $videoconvertor_option"
videoparameters=( `videoconvertor_get` )
echo "4 $videoconvertor_option"
wait_for
videoconvertor_doconvert
videoconvertor_destroy
echo "5 $videoconvertor_option"
terminate_wait_for
fi
exit 0