问题
在工作中,部署工具一般只负责把tar
/jar
包上传到公司的一个中心服务器C
上。如果我们在开发的服务器A
上,要部署最新代码运行,还需要费一番周折。
观察到的开发人员常用的一个方法是:从服务器C
先将包先下载到本机L
,然后再从本机L
上传到服务器A
。
当有多个项目(10+)时,这是一件非常繁琐的事。需要使用脚本将过程自动化。
中心服务器上的项目路径
在总目录/path/to/repository
下,有多个项目project_1
, project_2
, project_3
,每个项目内还有多个版本号。
/path/to/repository/project_1/p1_v1
/path/to/repository/project_1/p1_v2
/path/to/repository/project_1/p1_v3
/path/to/repository/project_2/p2_v1
/path/to/repository/project_2/p2_v2
/path/to/repository/project_3/p3_v1
/path/to/repository/project_3/p3_v2
/path/to/repository/project_3/p3_v3
/path/to/repository/project_3/p3_v4
我们需要下载的是,每个项目的最新版本:p1_v3
,p2_v2
,p3_v4
。
核心脚本
我们使用了wget
进行下载。这里,难点在于:
- 如何遍历所有的项目
- 如何将无关项过滤
- 如何选取最新版本
先上代码:
pkglst=$(wget -r --no-parent -A .tar -P temp /path/to/repository/ |& grep "some_key_word" | awk '{print $NF}' | sort -V | awk -F '/' '{ map[$(NF-2)]=$0;} END{for( key in map) print map[key];}')
echo "$pkglst" | while read line; do
echo $line
wget -r -A .tar -P temp --no-parent $line
done
下面做出说明:
download
wget -r
: specify recursive downloadwget --no-parent
: don’t ascend to the parent directorywget -A
: accepted extensionswget -P
: save files to
pipeline
|&
: equal to2>&1 |
2>&1
: almost equal to redirect stderr to stdout
grep "some_key_word"
: 使用关键词过滤掉无用的文件
awk '{print $NF}'
: 选取最后的一项,即/path/to/repository/project_1/p1_v1
,把时间戳过滤掉
sort -V
: 按照版本号排序
awk -F '/' '{map[$(NF-2)]=$0;} END{for(key in map) print map[key];}'
: 选择最大的版本号
关于这里的awk还要做出额外的说明:
首先,使用`/`作为分隔符,将整个字符串拆分。
然后,选取倒数第二个字段作为key,选取整个字符串作为value。
举例来说,就是[project_1] <-> [/path/to/repository/project_1/p1_v1]。
一条一条循环下来,[project_1]的value会被不断更新,最终停留在最后一个[/path/to/repository/project_1/p1_v3]。
因为上面已经按照版本号做过了排序,所以,最终留下即为最大版本号。
后续处理
在上面,我们将包下载到了一个temp的目录下,这里,需要将包从temp目录下导出到target目录下。
为什么要多一个temp目录呢?因为如果命令执行错误,或者网络错误,将只影响temp目录,而不会影响target目录。(最后文件拷贝的过程中的错误发生概率很小)
for f in $(find temp -name *package.tar); do
rm ./$(basename $f) &>/dev/null
mv $f $(basename $f)
if [[ $extract -eq 1 ]]
then
tar xvf $(basename $f)
rm ./$(basename $f) &>/dev/null
fi
echo $(basename $f) >>download_info.txt
done
这里的步骤就挺好理解了,就是rm
, mv
, 然后根据一个变量$extract
来决定要不要解压缩。
&>/dev/null
: redirect stdout and stderr to null, like throw to trash bin
总结
- 使用
wget
下载 - 使用
grep
,awk
,sort
过滤 - 使用
rm
,mv
等移动文件 - 使用
tar
解压缩