在工作中,有些活是富有创造力的,而有些活是相对繁重而重复的。如果转换一下思维,用一个另一个思路去做冗余的工作,可能就会轻松许多。
下面就是一个例子。
问题
我们系统的工作流如下:上游A系统把文件上传到B平台,然后C系统(我们)从B平台获取文件,并处理,再给下游系统使用。
A -> B -> C -> ...
一般,当A有内容变动时,需要先反映到B上,然后C(我们)再经由B拿到文件并做相关改动。
但是,上游系统A出于"种种原因",跳过了B,直接把新的文件塞给了我们,并且要求做出改动。(一开始我们是拒绝的,但是大佬们经过一轮"协商"后,还是得做)
A ->> C -> ...
本身,这个活就挺**的,更加让人产生负面情绪的是:
- 首先,这个给我们增加了风险。因为完整的流在开发测试中无法重现,相当于我们少测试了一环。
- 其次,我们因此增加了许多工作量。我们必须加一些hack逻辑,把
B->C
这个过程改成A->C
。
而且,增加的工作量非常巨大而且繁琐。A改了4个文件,但是在我们系统中,这4个文件被三十几个batch引用了,且每个batch要有一份只属于自己的文件。
也就是说,最终我们需要修改(拷贝,重命名,打包)4*30=120个文件!
而且,每进行一轮新的测试,就要重新准备一轮文件。我们一般从开发到上线至少做4-6轮测试,取中位数5的话,就是120*5=600个文件!
低效率的解决方案
具体到一个文件,需要怎么做呢?
- 首先,上游将文件F发给我们。
- 然后,对比文件名和目标文件名是否一致,如不一致需做出修改(一般需要加上日期)。
- 然后,将文件F压缩打包成G。
- 最后,将文件G上传至服务器指定位置,并替换原有同名文件。
我试了下,第一次做完上述操作(包括上传文件等待时间),花了5分钟,假设熟练之后,时间减半,耗时2.5分钟,一轮测试下来,光准备文件就需要2.5*120/60
=5小时!如果是按5轮测试来算的话,就是5*5=25小时!
高效率的解决方案
比较好的方法是,使用shell script将整个过程自动化。
- 首先,使用系统脚本下载原本的文件。
- 接着,将不需要的文件删除:
find ~/location/*oldfile* -type f -not -name '*specialfile*' -print0 | xargs -0 -I {} rm -v {}
。 - 接着,我将测试文件全部上传到服务器上
scp ./newfile ~/testfiles/newfile
- 然后,将测试文件加上日期:
mv ~/testfiles/newfile ~/testfiles/newfile_date
- 然后,将测试文件打包:
zip -j ~/testfiles/newfile_date.zip ~/testfiles/newfile_date;
- 最后,将新文件拷贝到目标路径:
cp ~/testfiles/newfile_date.zip ~/location/
将整个过程串联起来,就成了一个自动化脚本。
重复执行
这个脚本不是一次性的,我们需要可以重复地跑,这样每一轮新的测试,只需改一改参数,即可一键运行,完成文件的替换。
具体执行起来,命令是这样的:./prepfile.sh -a param_a -b param_b -c param_c
。
读取参数部分,可以参考以下:将param_a
,param_b
,param_c
适当修改,即可。
#!/bin/bash
#
# reference <https://unix.stackexchange.com/questions/31414/how-can-i-pass-a-command-line-argument-into-a-shell-script>
# note: input key needs to be one character, like 'd' for 'date', but not using 'date' directly
#
# Prep
helpFunction()
{
echo ""
echo "Usage: $0 -a param_a -b param_b -c param_c"
echo -e " -a, param_a"
echo -e " -b, param_b"
echo -e " -c, param_c"
exit 1 # Exit script after printing help
}
while getopts "a:b:c:" opt
do
case "$opt" in
a ) param_a="$OPTARG" ;;
b ) param_b="$OPTARG" ;;
c ) param_c="$OPTARG" ;;
? ) echo "parameter not right"; helpFunction ;; # Print helpFunction in case parameter is non-existent
esac
done
## Print helpFunction in case parameters are empty
if [ -z "$param_a" ] || [ -z "$param_b" ] || [ -z "$param_c" ]
then
echo "Some or all of the parameters are empty";
helpFunction
fi
# Begin script in case all parameters are correct
echo "param_a: $param_a"
echo "param_b: $param_b"
echo "param_c: $param_c"
最终,我花了2小时写脚本+调试,而之后的运行时间几乎可以忽略不记。(人可以干别的事儿去了,让机器自己跑着)
25 : 2,对比下来,优劣很明显,Shell Script帮我提升了10倍工作效率,从而我可以专注于真正有创造力的工作上。
总结
程序开发的本质,和流水线很像,将复杂工作简单化,再将重复工作自动化,一并交给机器去处理。在工作中,我们也需要有自动化思维,当工作繁琐,让人心力交瘁时,就要停下来想一想,是不是有办法改进。
我们的宗旨是:重复的冗余工作不应该做第二次!