简述
apt-cyg是Cygwin下的基于命令行的包管理工具, 它跟Cygwin官方的安装工具setup-x86.exe/setup-x86_64.exe使用相同的软件仓库.它使用Shell脚本编写, 里面调用了grep, awk, sed等文本处理工具, 是个学习Shell脚本的好例子.
官网地址
http://code.google.com/p/apt-cyghttps://github.com/transcode-open/apt-cyg
先决条件
wget bzip2 tar awk架构改变
Cgywin增加了64位系统的支持, 软件仓库的目录结构发生了改变, 分为了x86和x86_64两个目录.apt-cyg的作者并没有及时更改以适应新的目录结构, 但许多人已经提出解决方案:
https://github.com/transcode-open/apt-cyg/pull/1
http://www.zoublog.com/apt-cyg-install-cygwin-package
以下所述是基于新架构的. 点 这里下载我修改后的apt-cyg.
主要目录
下载缓存$cache
默认: /setup
$cache/$mirrordir/$arch
实例: /setup/http%3a%2f%2fmirrors.163.com%2fcygwin/x86
配置信息
/etc/setup
安装脚本
/etc/postinstall
移除脚本
/etc/preremove
相关文件
安装信息来源
$mirror/$arch/setup.bz2
实例: http://mirrors.163.com/cygwin/x86/setup.bz2
缓存
$cache/$mirrordir/$arch/setup.ini
实例: /setup/http%3a%2f%2fmirrors.163.com%2fcygwin/x86/setup.ini
$cache/$mirrordir/$arch/setup.ini-save
实例: /setup/http%3a%2f%2fmirrors.163.com%2fcygwin/x86/setup.ini-save
包描述文件
$cache/$mirrordir/release/$pkg/desc
注意: 相关信息是安装包时从setup.ini提取的
包下载文件
$cache/$mirrordir/$arch/release/$pkg/*.tar.gz2
实例: /setup/http%3a%2f%2fmirrors.163.com%2fcygwin/x86/release/nano/nano-2.2.6-1.tar.bz2
包清单文件
/etc/setup/$pkg.lst.gz
实例: /etc/setup/nano.lst.gz
已安装包列表
/etc/setup/installed.db
/etc/setup/installed.db-save
包安装脚本
/etc/postinstall/*.sh
包删除脚本
/etc/preremove/$pkg.sh
主要函数
usage() 显示使用说明findworkspace() 进入工作目录
getsetup() 获取安装信息
主要处理
处理参数: while test $# -gt 0处理命令: case "$command" in
安装处理
进入工作目录$cache/$mirrordir/$arch
更新安装信息
$cache/$mirrordir/$arch/setup.ini
检查包是否已安装
提取描述信息
保存描述信息
$cache/$mirrordir/release/$pkg/desc
下载压缩包
$mirror/$install
检验压缩包
解压压缩包
更新已安装包列表
/etc/setup/installed.db
递归安装依赖包
for package in $requires
执行所有安装脚本
/etc/postinstall/*.sh
安装完毕
移除处理
检查包是否已安装忽悠系统关键包
cygwin coreutils gawk bzip2 tar wget bash
运行包移除脚本(如果存在)
/etc/preremove/$pkg.sh
移除包移除脚本(如果存在)
/etc/preremove/$pkg.sh
移除包相关文件
/etc/setup/$pkg.lst.gz
移除包清单文件
/etc/setup/$pkg.lst.gz
移除包安装脚本
rm -f /etc/postinstall/$pkg.sh.done
更新已安装包列表
/etc/setup/installed.db
移除完毕
精彩代码
awk '/[^ ]+ [^ ]+ 0/ {if ($1 ~ query) print $1}' query="$pkg" /etc/setup/installed.db cat setup.ini | awk -v query="$pkg" \
'BEGIN{RS="\n\n@ "; FS="\n"; ORS="\n"} {if ($1 ~ query) {print $1}}'
cat setup.ini | awk -v query="$pkg" \
'BEGIN{RS="\n\n@ "; FS="\n"; ORS="\n"} {if ($1 ~ query) {print $0 "\n"}}'
cat setup.ini | awk > "release/$pkg/desc" -v package="$pkg" \
'BEGIN{RS="\n\n@ "; FS="\n"} {if ($1 == package) {desc = $0; px++}} \
END {if (px == 1 && desc != "") print desc; else print "Package not found"}'
cat /etc/setup/installed.db | awk > /tmp/awk.$$ -v pkg="$pkg" -v bz=$file \
'{if (ins != 1 && pkg < $1) {print pkg " " bz " 0"; ins=1}; print $0} \
END{if (ins != 1) print pkg " " bz " 0"}'
echo > /tmp/awk.$$ '/^requires: / {s=gensub("(requires: )?([^ ]+) ?", "\\2 ", "g", $0); print s}'
requires=`cat "release/$pkg/desc" | awk -f /tmp/awk.$$`
cat "/etc/setup/$pkg.lst.gz" | gzip -d | awk '/[^\/]$/ {print "rm -f \"/" $0 "\""}' | sh
cat /etc/setup/installed.db | awk > /tmp/awk.$$ -v pkg="$pkg" '{if (pkg != $1) print $0}'
值得注意的是, 很多cat $file | awk $program, 可以直接 awk $program $file 更好的.
解压错误
Unpacking...bunzip2: (stdin) is not a bzip2 file.
tar: 它似乎不像是一个 tar 归档文件
tar: 由于前次错误,将以上次的错误状态退出
修改/bin/apt-cyg, 找到echo "Unpacking..."下面的一行
cat $file | bunzip2 | tar > "/etc/setup/$pkg.lst" xvf - -C /
将其修改为下面即可
tar -xvf $file -C / > "/etc/setup/$pkg.lst"