installpkg 是用来安装 slackware 软件包的工具, 根据它的帮助, 可以知道它的各个参数:
-warn 只用来警告是否有文件被覆盖, 并不进行实际的安装
-root /mnt 用其它的目录来作根目录, 可以用在系统维护或是系统安装的时候, 如果没使用这个参数, 那么则使用环境变量中的 ROOT 设置
-infobox 安装的时候显示一个文本对话框, 以显信息
-menu 使用文本对话框来询问是否安装, 对指定了[required](ADD)优先级的包无效
-ask 和上一个参数(-menu)联合使用, 用以忽略优先级的设置, 即指定了
[required](ADD)优先级的包也要询问是否安装, 这是帮助中说的, 实际上,
从代码中看, 即使是 infobox 模式下, 或者是 skip 优先级, -ask 也是
有用的
-priority ADD|REC|OPT|SKP
手工指定包的优先级, 而不是从 tagfile 中读取. 可以使用的优先级有:
# ADD: required, 系统必需的软件
# REC: recommended, 推荐安装的软件
# OPT: optional, 可以选的软件
# SKP: skip, 忽略的软件
-tagfile /somedir/tagfile
手工指定 tagfile, 而不是使用默认的位置存放的 tagfile.
默认位置在软件包所在的目录.
installpkg 中还使用了 dialog 来显示文本界面的对话框, 主要用到了两种形式, 在此简单说明一下:
dialog --title "对话框标题" --infobox "显示的信息" 0 0
其中的 0 0 表示对话框的大小是自适应的
dialog --title "对话框标题" --menu "菜单的提示信息" 0 0 3 \
"第一个选项" "第一个选项的说明"
"第二个选项" "第二个选项的说明"
"第三个选项" "第三个选项的说明" 2>result.txt
其中的 0 0 表示对话框大小是自适应的, 3 表示有 3 个选项, “2>result.txt“表示把选择的结果放进 result.txt 中
下面是省去了版权信息及英文注释的中文注释了的代码(为了节约篇幅), 代码的相关版权请参照原软件包:
#!/bin/sh
# 默认返回 0, 如果后面遇到错误, 则重新设置 EXITSTATUS 的值
EXITSTATUS=0
# 检查 tar 的版本是否符合要求
umask 022
TAR=tar-1.13
$TAR --help 1> /dev/null 2> /dev/null
if [ ! $? = 0 ]; then
TAR=tar
fi
if [ ! "`LC_MESSAGES=C $TAR --version`" = "tar (GNU tar) 1.13
Copyright (C) 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by John Gilmore and Jay Fenlason." ]; then
echo "WARNING: pkgtools are unstable with tar > 1.13."
echo " You should provide a \"tar-1.13\" in your \$PATH."
sleep 5
fi
# 帮助信息
usage() {
cat << EOF
Usage: installpkg [options] package_name
Installpkg is used to install a .tgz package like this:
installpkg xf_bin.tgz
options: -warn (warn if files will be overwritten, but do not install)
-root /mnt (install someplace else, like /mnt)
-infobox (use dialog to draw an info box)
-menu (confirm package installation with a menu, unless
the priority is [required] or ADD)
-ask (used with menu mode: always ask if a package should be
installed regardless of what the package's priority is)
-priority ADD|REC|OPT|SKP (provide a priority for the entire
package list to use instead of the priority in the
tagfile)
-tagfile /somedir/tagfile (specify a different file to use
for package priorities. The default is "tagfile" in
the package's directory)
EOF
}
# 消除多余的空白
# 后面用它来处理 gzip -l 的输出, 并将处理完的结果送给 cut,
# 避免了多个空白对 cut 的处理
crunch() {
while read FOO ; do
echo $FOO
done
}
# 由软件包的文件名获取相应的软件名
# 支持老式包名(软件名.tgz)和新式包名(软件名-版本号-平台-打包次数.tgz)
package_name() {
# 去掉结尾的 .tgz
STRING=`basename $1 .tgz`
# 检查是否是老式包名
# 当包名中不含 "-" 的时候,"cut -f 1 -d -" 和 "cut -f 2 -d -" 的执行结果相同,
# 此处通过这个特性来确定包名中是否含有 "-", 这是不严密的, 因为可能会存在第一
# 段和第二段内容相同的情况(应该很少见). 为什么不直接比较 cut -f 1 -d - 和
# $STRING 本身呢?
if [ "`echo $STRING | cut -f 1 -d -`" = "`echo $STRING | cut -f 2 -d -`" ]; then
echo $STRING
else
# 包名中包含 "-", 不过有可能是因为软件名中含有 "-"(例如: util-linux),
# 所以仍有可能是老式包名
# 计算文件名被 "-" 分割为了几段, 少于4段的则仍旧为老式的文件名
INDEX=1
while [ ! "`echo $STRING | cut -f $INDEX -d -`" = "" ]; do
INDEX=`expr $INDEX + 1`
done
INDEX=`expr $INDEX - 1`
# 少于4段的, 就仍然是旧式的软件包
if [ "$INDEX" = "2" -o "$INDEX" = "3" ]; then
echo $STRING
else
# 多于 4 段, 为新式文件名(此做法有一定的限制: 在软件名中包含大于等于 3 个
# "-"的时候会误判,不过目前没见到过有这样的软件名)
# 由于版本号,平台和打包次数均不含 "-",所以从后面去掉三段(显示从第 1 段到第
# $INDEX - 3 段),剩下的部分作为软件名,这样能正确处理软件名中包含"-"的情况
NAME=`expr $INDEX - 3`
NAME="`echo $STRING | cut -f 1-$NAME -d -`"
echo $NAME
# cruft for later ;)
#VER=`expr $INDEX - 2`
#VER="`echo $STRING | cut -f $VER -d -`"
#ARCH=`expr $INDEX - 1`
#ARCH="`echo $STRING | cut -f $ARCH -d -`"
#BUILD="`echo $STRING | cut -f $INDEX -d -`"
fi
fi
}
# 参数处理, installpkg 程序的真正入口
# 默认为 install 模式(命令行安装模式)
MODE=install
while [ 0 ]; do
# warn 模式(只提示要安装, 删除哪些东西, 但是并不真正执行)
if [ "$1" = "-warn" ]; then
MODE=warn
shift 1
# infobox 模式(使用文本对话框来显安装信息, 但是无需选择是否安装)
elif [ "$1" = "-infobox" ]; then
MODE=infobox
shift 1
# menu 模式(使用文本对话框来询问是否要安装, 不询问优先级为[required]的软件包)
elif [ "$1" = "-menu" ]; then
MODE=menu
shift 1
# menu 模式下, 即使优先级为[required]的软件包, 也询问是否安装
elif [ "$1" = "-ask" ]; then
ALWAYSASK="yes"
shift 1
# 使用用户指定的 tagfile
elif [ "$1" = "-tagfile" ]; then
if [ -r "$2" ]; then
USERTAGFILE="$2"
elif [ -r "`pwd`/$2" ]; then
USERTAGFILE="`pwd`/$2"
else
usage
exit
fi
shift 2
# 使用用户指定的优先级
elif [ "$1" = "-priority" ]; then
if [ "$2" = "" ]; then
usage
exit
fi
USERPRIORITY="$2"
shift 2
# 指定其它的安装位置, 可以用在系统安装或者是维护的时候
elif [ "$1" = "-root" ]; then
if [ "$2" = "" ]; then
usage
exit
fi
ROOT="$2"
shift 2
else
# 遇到第一个非以上众多参数之一的, 则退出参数处理
# 后面的参数都会被当作是软件名, 这是 installpkg 的一个限制:
# 比如 installpkg packagename.tgz -warn 中的 -warn 也会被认为是个软件包名
break
fi
done
# 检查所需目录结构是否存在, 并且是否是目录, 如果不是, 则建立, 并设置好相应权限
# 相应的目录有 /var/log/packages, /var/log/removed_packages,
# /var/log/removed_scripts, /var/log/scripts, /var/log/setup
ADM_DIR="$ROOT/var/log"
for PKGDBDIR in packages removed_packages removed_scripts scripts setup ; do
if [ ! -d $ADM_DIR/$PKGDBDIR ]; then
rm -rf $ADM_DIR/$PKGDBDIR # make sure it's not a symlink or something stupid
mkdir -p $ADM_DIR/$PKGDBDIR
chmod 755 $ADM_DIR/$PKGDBDIR
fi
done
# 检查是否有临时目录
TMP=$ADM_DIR/setup/tmp
# If the $TMP directory doesn't exist, create it:
if [ ! -d $TMP ]; then
rm -rf $TMP # make sure it's not a symlink or something stupid
mkdir -p $TMP
chmod 700 $TMP
fi
# 无参数(或者是处理完 -warn 之类的参数后没有软件包名称)时显示帮助
if [ $# = 0 ]; then
usage;
exit
fi
# warn 模式
if [ "$MODE" = "warn" ]; then
# 循环处理所有的包
while [ -f "$1" ]; do
echo "#### Scanning the contents of $1..."
mkdir -p $TMP/scan$$
# 在括号中的命令会使用一个子 shell, 在这个子 shell 中的 cd 命令不会影响到
# installpkg 自身的工作目录
( cd $TMP/scan$$ ; $TAR xzf - install ) < $1 2> /dev/null
if [ -r $TMP/scan$$/install/doinst.sh ]; then
# 包中包含 install/doinst.sh, 且其中包含 ' rm -rf' 的内容
if cat $TMP/scan$$/install/doinst.sh | grep ' rm -rf ' 1>/dev/null 2>/dev/null ; then
# 收集含有 ' rm -rf' 的行,并处理后输出
cat $TMP/scan$$/install/doinst.sh | grep ' rm -rf ' > $TMP/scan$$/install/delete
echo "The following locations will be completely WIPED OUT to allow symbolic"
echo "links to be made. (We're talking 'rm -rf') These locations may be files,"
echo "or entire directories. Be sure you've backed up anything at these"
echo "locations that you want to save before you install this package:"
cat $TMP/scan$$/install/delete | cut -f 3,7 -d ' ' | tr ' ' '/'
fi
if [ -d $TMP/scan$$ ]; then
# 直接使用
# rm -rf $TMP/scan$$/install 2>/dev/null
# rmdir scan$$ 2>/dev/null
# 不是更好?
# 另: 不直接使用 rm -rf $TMP/scan$$ 2>/dev/null 是因为 rmdir 只删除
# 空目录, 所以不会影响 $TMP/scan$$ 下的的其它文件(如果存在的话)
( cd $TMP/scan$$ ; rm -rf install ) 2> /dev/null
( cd $TMP ; rmdir scan$$ ) 2> /dev/null
fi
fi
echo "The following files will be overwritten when installing this package."
echo "Be sure they aren't important before you install this package:"
# tar 的 vv 参数会让 tar 显示更详细的文件信息(列出文件类型权限等),
# 这样就可以用来过滤掉目录
# 下面的这个地方没必要用这个括号, 直接 $TAR tzvvf $1 | grep -v 'drwx' 就可以
# 在这可以看出, warn 模式给出的提示只是 *可能* 会被覆盖的
( $TAR tzvvf - ) < $1 | grep -v 'drwx'
echo
shift 1
done
# 全部的包都 warn 完之后退出, 不进行后面的安装
exit
fi
# 各种安装模式(install, infobox, menu 模式)
for package in $* ; do
# 运行命令时包名称未带 .tgz 则加上,以便统一处理
if [ ! -r "$package" -a -r "$package.tgz" ]; then
package=$package.tgz
fi
# 去掉包名中的 .tgz 部分
shortname="`basename $package .tgz`"
# 包所在的目录
packagedir="`dirname $package`"
# 调用 package_name 函数来获取软件名
packagebase="`package_name $shortname`"
# 拒绝非 .tgz 结尾的包(设置返回值为 3)
# 前面已经有 packagedir='`dirname $package`", 为什么这里不直接使用?
if [ ! -r "`dirname $package`/$shortname.tgz" ]; then
EXITSTATUS=3
if [ "$MODE" = "install" ]; then
echo "Cannot install $package: package does not end in .tgz"
fi
continue;
fi
# 处理包的优先级
unset PRIORITY
if [ "$USERTAGFILE" = "" ]; then
# 同样, 前面已经有 packagedir='`dirname $package`", 为什么这里不直接使用?
TAGFILE="`dirname $package`/tagfile"
else
TAGFILE="$USERTAGFILE"
fi
if [ ! -r "$TAGFILE" ]; then
TAGFILE=/dev/null
fi
# 读取优先级信息:
if grep "^$packagebase:" "$TAGFILE" | grep ADD > /dev/null 2> /dev/null ; then
PRIORITY="ADD"
elif grep "^$packagebase:" "$TAGFILE" | grep REC > /dev/null 2> /dev/null ; then
PRIORITY="REC"
elif grep "^$packagebase:" "$TAGFILE" | grep OPT > /dev/null 2> /dev/null ; then
PRIORITY="OPT"
elif grep "^$packagebase:" "$TAGFILE" | grep SKP > /dev/null 2> /dev/null ; then
PRIORITY="SKP"
fi
# 根据不同的优先级, 设定 PMSG, 用于后面的显示
if [ "$PRIORITY" = "ADD" ]; then
PMSG="[required]"
elif [ "$PRIORITY" = "REC" ]; then
PMSG="[recommended]"
elif [ "$PRIORITY" = "OPT" ]; then
PMSG="[optional]"
elif [ "$PRIORITY" = "SKP" ]; then
PMSG="[skip]"
else
PMSG=""
fi
# 获取软件包相应的描述文件
DESCRIPTION="/dev/null"
# 在软件包相同的目录下查找 disk* package_descriptions $shortname.txt
# $packagebase.txt, 看是否含有描述信息
for file in $packagedir/disk* $packagedir/package_descriptions $packagedir/$shortname.txt $packagedir/$packagebase.txt ; do
if grep "^$packagebase:" "$file" 1> /dev/null 2> /dev/null ; then
DESCRIPTION="$file"
elif grep "^$shortname:" "$file" 1> /dev/null 2> /dev/null ; then
DESCRIPTION="$file"
fi
done
# 未在软件包外找到描述文件, 则在软件包内查找. 需要解压缩
if [ "$DESCRIPTION" = "/dev/null" ]; then
mkdir -p $TMP/scan$$
# 常用的方法, 在子 shell 中改变工作目录, 从而不影响整个脚本的工作目录
( cd $TMP/scan$$ ; $TAR xzf - install ) < $package 2> /dev/null
if grep "^$packagebase:" "$TMP/scan$$/install/slack-desc" 1> /dev/null 2> /dev/null ; then
DESCRIPTION="$TMP/scan$$/install/slack-desc"
elif grep "^$shortname:" "$TMP/scan$$/install/slack-desc" 1> /dev/null 2> /dev/null ; then
DESCRIPTION="$TMP/scan$$/install/slack-desc"
fi
fi
# 包合法性检查
if [ ! -f $package ]; then # 非普通文件
EXITSTATUS=4
if [ "$MODE" = "install" ]; then
echo "Cannot install $package: package is not a regular file"
fi
continue;
fi
gzip -l $package 1> /dev/null 2> /dev/null
if [ ! "$?" = "0" ]; then # 无法用 gzip -l 来操作软件包
EXITSTATUS=2 # failed gzip -l
if [ "$MODE" = "install" ]; then
echo "Cannot install $package: package is corrupt (failed 'gzip -l $package')"
fi
continue;
fi
# 获取压缩前后的文件大小信息, 存入临时文件
COMPRESSED=`gzip -l $package | grep -v uncompressed_name | crunch | cut -f 1 -d ' '`
UNCOMPRESSED=`gzip -l $package | grep -v uncompressed_name | crunch | cut -f 2 -d ' '`
COMPRESSED="`expr $COMPRESSED / 1024` K"
UNCOMPRESSED="`expr $UNCOMPRESSED / 1024` K"
# MD5SUM=`md5sum $package | cut -f 1 -d ' '`
cat $DESCRIPTION | grep "^$packagebase:" | cut -f 2- -d : | cut -b2- 1> $TMP/tmpmsg$$ 2> /dev/null
if [ "$shortname" != "$packagebase" ]; then
cat $DESCRIPTION | grep "^$shortname:" | cut -f 2- -d : | cut -b2- 1>> $TMP/tmpmsg$$ 2> /dev/null
fi
# slackware 包的描述文件最高为 13 行, 少于 12 行时用空行补到 12 行(最后一行为文件尺寸信息)
LENGTH=`cat $TMP/tmpmsg$$ | wc -l`
while [ $LENGTH -lt 12 ]; do
echo >> $TMP/tmpmsg$$
LENGTH=`expr $LENGTH + 1`
done
# 第 13 行, 文件尺寸信息
echo "Size: Compressed: $COMPRESSED, uncompressed: $UNCOMPRESSED." >> $TMP/tmpmsg$$
# 根据英文的注释, 新版本的 dialog 需要在每一行的末尾多加一个 '\n',
# 否则输出的内容会比较混乱, 但是似乎不是所有版本的 dialog 都这样,
# 不过就算加上也不会有什么影响
cat << EOF > $TMP/controlns$$
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
EOF
# 将提取出来的软件描述和 dialog 需要的行尾 '\n' 连接起来
# -d "" 表示两个文件的对应行连接的时候用 "" 来分隔, 其实就是中间不加入分隔
paste -d "" $TMP/tmpmsg$$ $TMP/controlns$$ > $TMP/pasted$$
rm -f $TMP/controlns$$
mv $TMP/pasted$$ $TMP/tmpmsg$$
# install 模式,不理会优先级的设定, 即使是 SKP 的软件也安装
if [ "$MODE" = "install" ]; then
if [ "$PMSG" = "" ]; then
echo "Installing package $shortname... "
else
echo "Installing package $shortname ($PMSG)... "
fi
echo "PACKAGE DESCRIPTION:"
cat $DESCRIPTION | grep "^$packagebase:" | uniq
if [ "$shortname" != "$packagebase" ]; then
cat $DESCRIPTION | grep "^$shortname:" | uniq
fi
# infobox 模式, 不安装 SKP 优先级的软件
elif [ "$MODE" = "infobox" -a ! "$PRIORITY" = "SKP" ]; then
dialog --title "Installing package ==>$shortname<== $PMSG" --infobox "`cat $TMP/tmpmsg$$`" 0 0
# menu 模式下, 优先级为 ADD(required) 的包, 并且未使用 -ask 参数要求询问,
# 则无需询问, 直接用 dialog 显示相关信息
elif [ "$MODE" = "menu" -a "$PRIORITY" = "ADD" -a ! "$ALWAYSASK" = "yes" ]; then
dialog --title "Installing package ==>$shortname<== $PMSG" --infobox "`cat $TMP/tmpmsg$$`" 0 0
# menu 模式下, 用户指定优先级为 ADD(required) 的包, 不管包原先的优先级是什么
# 都无需询问, 直接用 dialog 显相关信息
elif [ "$MODE" = "menu" -a "$USERPRIORITY" = "ADD" ]; then
dialog --title "Installing package ==>$shortname<== $PMSG" --infobox "`cat $TMP/tmpmsg$$`" 0 0
# menu/infobox 模式下, 优先级为 SKP 的包, 且未使用 -ask 参数要求询问,
# 则直接删除临时文件, 不作其它处理
elif [ "$MODE" = "menu" -a "$PRIORITY" = "SKP" -a ! "$ALWAYSASK" = "yes" ]; then
rm -f $TMP/tmpmsg$$
continue # 处理下一个软件包
# infobox 模式, skip 优先级, 无 -ask, 则直接删除临时文件, 不作其它处理
# 从下面这一条和上面这一条可以看出, -ask 并不像帮助中说的那样, 只对 warn 模式或
# ADD 优先级起作用
elif [ "$MODE" = "infobox" -a "$PRIORITY" = "SKP" -a ! "$ALWAYSASK" = "yes" ]; then
rm -f $TMP/tmpmsg$$
continue
# 剩下的情况都是需要使用菜单来询问是否真的要安装
else
dialog --title "Package Name: ==>$shortname<== $PMSG" --menu "`cat $TMP/tmpmsg$$`" 0 0 3 \
"Yes" "Install package $shortname" \
"No" "Do not install package $shortname" \
"Quit" "Abort software installation completely" 2> $TMP/reply$$
# 当选择的是上面三个选项的时候, dialog 返回 0,
# 而当直接选择"取消"按钮, 则返回非 0, 与选择 No 选项一样处理
if [ ! $? = 0 ]; then
echo "No" > $TMP/reply$$
fi
REPLY="`cat $TMP/reply$$`"
rm -f $TMP/reply$$ $TMP/tmpmsg$$
if [ "$REPLY" = "Quit" ]; then
# 返回值 99: 用户选择 Quit, 退出 *所有的* 软件包的安装, 不光是当前这一个
exit 99
elif [ "$REPLY" = "No" ]; then
continue # 用户选择不安装本软件包, 跳过
fi
fi
# 得到将要安装的文件列表
$TAR tzf $package 1> $TMP/tmplist$$ 2> /dev/null
TARERROR=$?
# 无法用 tar tzf 列出包的内容, tar 包不正确
if [ ! "$TARERROR" = "0" ]; then
EXITSTATUS=1
if [ "$MODE" = "install" ]; then
echo "Unable to install $package: tar archive is corrupt (tar returned error code $TARERROR)"
fi
rm -f $TMP/tmplist$$
continue
fi
# 删除文件列表中的符号链接
cat $TMP/tmplist$$ | grep -v "/$" | while read file ; do
if [ -L "$ROOT/$file" ]; then
rm -f "$ROOT/$file"
fi
done
rm -f $TMP/tmplist$$
# 记录将要安装的包的信息
echo "PACKAGE NAME: $shortname" > $ADM_DIR/packages/$shortname
echo "COMPRESSED PACKAGE SIZE: $COMPRESSED" >> $ADM_DIR/packages/$shortname
echo "UNCOMPRESSED PACKAGE SIZE: $UNCOMPRESSED" >> $ADM_DIR/packages/$shortname
echo "PACKAGE LOCATION: $package" >> $ADM_DIR/packages/$shortname
# echo "PACKAGE MD5SUM: $MD5SUM" >> $ADM_DIR/packages/$shortname
echo "PACKAGE DESCRIPTION:" >> $ADM_DIR/packages/$shortname
cat $DESCRIPTION | grep "^$packagebase:" >> $ADM_DIR/packages/$shortname 2> /dev/null
if [ "$shortname" != "$packagebase" ]; then
cat $DESCRIPTION | grep "^$shortname:" >> $ADM_DIR/packages/$shortname 2> /dev/null
fi
echo "FILE LIST:" >> $ADM_DIR/packages/$shortname
# 此处使用了很多的 tar 参数, 其中关键的有:
# -U 在解压要重写的文件前先删除它们,避免了覆盖已存在文件时的问题
# -p 解包时保留文件的权限信息, 软件包中的文件的权限在安装的时候是应该保留的
# -v 显示出解包出来的文件列表, 用它来记录所安装的文件/目录
# 此外还有一个 -l, 它在 gnu tar 1.13 版的时候表示 --one-file-system,
# 而 gnu tar 1.14 之后就不再赞成使用 -l 表示 --one-file-system 了, 到了 gnu tar 1.15.91
# 之后 -l 就表示 --check-links 了, 这大概也是 pkgtools 中非要用 tar 1.13 的原因吧.
# 但是 gnu 的文档中说: "Used when creating an archive.", 是不是表示这里可以不要这个 -l?
( cd $ROOT/ ; $TAR -xzlUpvf - ) < $package >> $TMP/$shortname 2> /dev/null
# 这个地方的 grep 是有问题的, slackware 期望要安装的文件列表里面有且只有一个
# 行首为 "./" 的行, 而这里的 grep '^./' 查找的是行首为一个字符后面跟着 "/" 的行,
# 所以当包内的文件中含有单个字母名称的目录时就会出现问题
if [ "`cat $TMP/$shortname | grep '^./' | wc -l | tr -d ' '`" = "1" ]; then
# Good. We have a package that meets the Slackware spec.
cat $TMP/$shortname >> $ADM_DIR/packages/$shortname
else
# 非 makepkg 制作的包的内容可能不符合 pkgtools 所需要的格式,则在记录中作出相应调整
echo './' >> $ADM_DIR/packages/$shortname
cat $TMP/$shortname | grep -v '^./$' | cut -b3- >> $ADM_DIR/packages/$shortname
fi
rm -f $TMP/$shortname
# 如果 ldconfig 可以执行,则运行它,这个是 glibc 的某种机制,相应可参考 LFS 的相关手册
if [ -x /sbin/ldconfig ]; then
/sbin/ldconfig
fi
# 执行安装脚本
# 此处执行安装脚本的时候传递了 -install 参数, 但是实际上脚本中未必会理会这个参数,
# 而 removepkg/upgradepkg 中也没有用到 doinst.sh, 大概是为了以后的扩展吧.
if [ -f $ROOT/install/doinst.sh ]; then
if [ "$MODE" = "install" ]; then
echo "Executing install script for $shortname..."
fi
( cd $ROOT/ ; sh install/doinst.sh -install; )
fi
# 将 $ROOT/install 下的相关内容移动到包记录的目录下
if [ -d $ROOT/install ]; then
if [ -r $ROOT/install/doinst.sh ]; then
cp $ROOT/install/doinst.sh $ADM_DIR/scripts/$shortname
chmod 755 $ADM_DIR/scripts/$shortname
fi
# 删除 /install/doinst.sh /install/slack-*,而如果 /install 下存在其它文件,不删除,
# 这说明 slackware 的包管理系统只占用了这样的几个文件名
( cd $ROOT/install ; rm -f doinst.sh slack-* 1> /dev/null 2>&1 )
rmdir $ROOT/install 1> /dev/null 2>&1
fi
# 删除临时文件
if [ -d "$TMP/scan$$" ]; then
rm -rf "$TMP/scan$$"
fi
rm -f $TMP/tmpmsg$$ $TMP/reply$$
# install 模式下安装完成后再输出一个空行,作为提示和分隔
if [ "$MODE" = "install" ]; then
echo
fi
done
exit $EXITSTATUS