面向对象 Bash 脚本带图形界面编程测试

测试了一下用面向对象的思维方式进行 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