有时候我们需要发布自己的程序给第三方安装使用,最简单的方法是将待发布的文件加上一个install安装脚本一起打包发布。后来机缘巧合下发现一款linux游戏的安装包只有一个安装脚本就实现了离线安装,出于好奇研究了下脚本实现,发现他们使用了简单的技巧将安装文件整体打包后追加到了脚本文件的末端,由脚本实现自解压以及后续的安装动作。
本文利用这个技巧实现了一个简易的安装程序,方便大家参考,脚本如下:
#!/bin/sh
print_services() {
...
exit 0
}
if [ $# -eq 1 -a "${1}" = "--service" ]; then
print_services
exit 0
else
skip=23
prog="./.agent.tmp"
rm -rf ${prog}
tail -n +${skip} "$0" >${prog}
chmod u+x ${prog}
${prog} $*
rm -rf ${prog}
exit 0
fi
可以看到,脚本里最为关键的地方是tail -n +${skip} "$0" >${prog},$0指向当前脚本文件,tail -n +${skip}需要指向脚本文本最末一行的下一行(就是追加的二进制文件的起始行),并将该行至脚本文件的末尾输出到${prog}指向的文件,最后执行实际的prog安装程序。这就是脚本自解压的过程,脚本制作也很简单,脚本编写完成后,留意下脚本文件的行数,将skip设定到末尾的下一行,之后用dd命令将二进制文件追加到脚本文件末尾即可。
后面搞明白了,有个开源工具makeself专门用来制作这种自解压的shell安装程序,很多游戏和商业软件的安装.run程序都是用makeself自动打包生成的,本文描述的就是makeself的底层实现方法。